Ariver
2026-08-22 1ec08b1dedff313e385767edb0c2b815b6dd56f3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env bash
set -euo pipefail
 
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
APP_BUNDLE="${1:-$ROOT_DIR/build/TagLauncher.app}"
EXPECTED_MINIMUM_SYSTEM="${MACOS_DEPLOYMENT_TARGET:-14.0}"
EXPECTED_ARCHES_RAW="${EXPECTED_ARCHES:-arm64}"
INFO_PLIST="$APP_BUNDLE/Contents/Info.plist"
EXECUTABLE="$APP_BUNDLE/Contents/MacOS/TagLauncher"
 
fail() {
  echo "FAIL: $*" >&2
  exit 1
}
 
[[ -d "$APP_BUNDLE" ]] || fail "app bundle not found: $APP_BUNDLE"
[[ -f "$INFO_PLIST" ]] || fail "Info.plist not found: $INFO_PLIST"
[[ -x "$EXECUTABLE" ]] || fail "executable not found or not executable: $EXECUTABLE"
 
unreadable_dirs="$(find "$APP_BUNDLE" -type d ! -perm -005 -print | head -20)"
if [[ -n "$unreadable_dirs" ]]; then
  fail "app bundle contains directories not readable/searchable by non-root users: $unreadable_dirs"
fi
 
unreadable_files="$(find "$APP_BUNDLE" -type f ! -perm -004 -print | head -20)"
if [[ -n "$unreadable_files" ]]; then
  fail "app bundle contains files not readable by non-root users: $unreadable_files"
fi
 
if find "$EXECUTABLE" -type f ! -perm -005 -print | grep -q .; then
  fail "main executable is not readable/executable by non-root users: $EXECUTABLE"
fi
 
SIGNED_ENTITLEMENTS="$(mktemp -t taglauncher-signed-entitlements.XXXXXX)"
PROFILE_PLIST="$(mktemp -t taglauncher-profile.XXXXXX)"
cleanup() {
  rm -f "$SIGNED_ENTITLEMENTS" "$PROFILE_PLIST"
}
trap cleanup EXIT
 
codesign -d --entitlements :- "$APP_BUNDLE" > "$SIGNED_ENTITLEMENTS" 2>/dev/null || fail "unable to read signed entitlements from $APP_BUNDLE"
if [[ -f "$APP_BUNDLE/Contents/embedded.provisionprofile" ]]; then
  security cms -D -i "$APP_BUNDLE/Contents/embedded.provisionprofile" > "$PROFILE_PLIST"
  profile_application_identifier="$(/usr/libexec/PlistBuddy -c 'Print :Entitlements:com.apple.application-identifier' "$PROFILE_PLIST" 2>/dev/null || true)"
  if [[ -n "$profile_application_identifier" ]]; then
    signed_application_identifier="$(/usr/libexec/PlistBuddy -c 'Print :com.apple.application-identifier' "$SIGNED_ENTITLEMENTS" 2>/dev/null || true)"
    [[ "$signed_application_identifier" == "$profile_application_identifier" ]] || fail "signed application identifier '$signed_application_identifier' does not match provisioning profile '$profile_application_identifier'"
  fi
fi
 
actual_minimum_system="$(/usr/libexec/PlistBuddy -c 'Print :LSMinimumSystemVersion' "$INFO_PLIST")"
if [[ "$actual_minimum_system" != "$EXPECTED_MINIMUM_SYSTEM" ]]; then
  fail "LSMinimumSystemVersion expected $EXPECTED_MINIMUM_SYSTEM, got $actual_minimum_system"
fi
 
EXPECTED_ARCHES=()
while IFS= read -r arch; do
  [[ -n "$arch" ]] && EXPECTED_ARCHES+=("$arch")
done < <(tr ',' '\n' <<<"$EXPECTED_ARCHES_RAW" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
 
[[ "${#EXPECTED_ARCHES[@]}" -gt 0 ]] || fail "no EXPECTED_ARCHES configured"
 
actual_arches="$(lipo -archs "$EXECUTABLE")"
for expected_arch in "${EXPECTED_ARCHES[@]}"; do
  case "$expected_arch" in
    arm64|x86_64) ;;
    *) fail "unsupported expected arch: $expected_arch" ;;
  esac
  if ! grep -Eq "(^|[[:space:]])${expected_arch}($|[[:space:]])" <<<"$actual_arches"; then
    fail "missing architecture $expected_arch; actual arches: $actual_arches"
  fi
done
 
for actual_arch in $actual_arches; do
  matched=false
  for expected_arch in "${EXPECTED_ARCHES[@]}"; do
    if [[ "$actual_arch" == "$expected_arch" ]]; then
      matched=true
      break
    fi
  done
  [[ "$matched" == true ]] || fail "unexpected architecture $actual_arch; expected: ${EXPECTED_ARCHES[*]}"
done
 
for arch in "${EXPECTED_ARCHES[@]}"; do
  build_info="$(vtool -arch "$arch" -show-build "$EXECUTABLE")"
  minos="$(awk '/minos/{print $2; exit}' <<<"$build_info")"
  [[ "$minos" == "$EXPECTED_MINIMUM_SYSTEM" ]] || fail "$arch LC_BUILD_VERSION minos expected $EXPECTED_MINIMUM_SYSTEM, got $minos"
done
 
codesign --verify --deep --strict "$APP_BUNDLE"
 
echo "PASS build metadata: LSMinimumSystemVersion=$actual_minimum_system minos=$EXPECTED_MINIMUM_SYSTEM arches=$actual_arches"