zeppossimulator

LOW
maintainer huntergrey 2 votes scanned 2026-09-17 00:27:14.276658
View on AUR
Why flagged

The package downloads a prebuilt .deb from a plausible project-owned CDN (zepp.com domain) and extracts it; the source is not built from scratch but the host is official and the content is verified via fixed checksum, limiting supply-chain risk to the integrity of the vendor's release.

Triggered rules

Low AI review downgraded a static finding llm_review

The static rules flagged this MEDIUM, but an AI model (qwen/qwen3-235b-a22b-2507) reviewed the full PKGBUILD and judged it LOW (confidence 95%): The package downloads a prebuilt .deb from a plausible project-owned CDN (zepp.com domain) and extracts it; the source is not built from scratch but the host is official and the content is verified via fixed checksum, limiting supply-chain risk to the integrity of the vendor's release.

1 higher static finding superseded - not the current verdict (shown for transparency)
Medium source=() URL on a non-standard host source_untrusted_domain

One or more source=() URLs point to a host outside the trusted allowlist (github.com, gitlab.com, codeberg.org, pypi.org, …).

  • PKGBUILD:40 source=("https://upload-cdn.zepp.com/zepp-applet-and-wechat-applet/${_date}/${_deb}")

PKGBUILD

1 offending line(s) highlighted
1# Maintainer: Hunter Grey <grey@huntergrey.cn>
2# Contributor: level666 <lev3l666@gmail.com>
3
4pkgname=zeppossimulator
5pkgver=2.1.2
6pkgrel=1
7pkgdesc="Simulator for developing Zepp OS mini programs and watchfaces"
8arch=('x86_64')
9url="https://zeppos.com/developer/simulator/"
10# Proprietary Zepp EULA, which upstream does not ship in the .deb - only the
11# Electron and Chromium notices are there, and those are what land in
12# /usr/share/licenses. Terms live at the url above.
13license=('LicenseRef-custom')
14options=('!strip' '!debug')
15
16# Taken from the NEEDED entries of every ELF in the .deb, mapped to the package
17# that owns each soname. glibc and gcc-libs are implicit and left out.
18depends=(
19 # Electron
20 'alsa-lib' 'at-spi2-core' 'cairo' 'dbus' 'expat' 'gdk-pixbuf2' 'glib2'
21 'gtk3' 'libcups' 'libdrm' 'libx11' 'libxcb' 'libxcomposite' 'libxdamage'
22 'libxext' 'libxfixes' 'libxkbcommon' 'libxrandr' 'mesa' 'nspr' 'nss' 'pango'
23
24 # bundled qemu-system-arm
25 'gnutls' 'libaio' 'libepoxy' 'libjpeg-turbo' 'libpng' 'libsasl' 'numactl'
26 'pixman' 'sdl2-compat' 'vte3' 'zlib'
27
28 # dlopened by name, so they have no NEEDED entry to be found by
29 'libnotify' 'libsecret' 'xdg-utils'
30)
31optdepends=('libappindicator-gtk3: tray icon support')
32
33# Upstream files every build under the date it was published, so the directory
34# changes with each release. The download table is rendered client side at
35# https://docs.zepp.com/docs/guides/tools/simulator/download/ ; the machine
36# readable copy is docs/guides/tools/simulator/download.md in
37# https://github.com/zepp-health/zeppos-docs
38_date=20260717
39_deb="simulator_${pkgver}_linux_amd64.deb"
40source=("https://upload-cdn.zepp.com/zepp-applet-and-wechat-applet/${_date}/${_deb}")
41noextract=("$_deb")
42sha256sums=('ab9b35c04ae5b016965fe7d051507b5b5a2eb7b5c0f85059294c1004d2be9aa0')
43
44# Every fixup in package() rests on an assumption about upstream's layout, and
45# `rm -f` on a path that moved is how a silently broken package ships. 2.1.2
46# already dropped the bogus 0x0 icon directory that 2.1.1 needed rescuing from,
47# so this is not hypothetical. Assert first and let the build fail loudly.
48# exit rather than return, so a missing path aborts regardless of errexit,
49# and print by hand rather than borrowing makepkg's error(), which is internal.
50_die() { printf '==> ERROR: %s\n' "$*" >&2; exit 1; }
51_expect() { [[ -e $1 ]] || _die "upstream layout changed: $1 is gone"; }
52
53package() {
54 bsdtar -xOf "$_deb" data.tar.xz | bsdtar -xJf - -C "$pkgdir"
55
56 local _app="$pkgdir/opt/simulator"
57 local _fw="$_app/resources/firmware"
58
59 # The .deb ships these 0644; upstream's postinst papered over it with a
60 # blanket `chmod 777 -R /opt/simulator`. Nothing writes into /opt at runtime
61 # (state lives in ~/.zepp), so keep the tree read-only and just fix the modes.
62 _expect "$_fw/qemu_linux/qemu-system-arm"
63 _expect "$_fw/start_qemu.sh"
64 chmod 755 "$_fw/qemu_linux/qemu-system-arm" "$_fw/start_qemu.sh"
65
66 # Arch ships cyrus-sasl 2.1.28 as libsasl2.so.3; Debian ships the same
67 # version with its soname frozen at .2. start_qemu.sh already puts this
68 # directory on LD_LIBRARY_PATH, so the shim stays out of /usr/lib. Guarded,
69 # because once upstream rebuilds qemu against a current sasl this symlink
70 # would just be a dangling file nobody notices.
71 if readelf -d "$_fw/qemu_linux/qemu-system-arm" | grep -q 'libsasl2\.so\.2'; then
72 ln -s /usr/lib/libsasl2.so.3 "$_fw/qemu_linux/lib/libsasl2.so.2"
73 else
74 _die "qemu no longer links libsasl2.so.2 - drop this shim and libsasl"
75 fi
76
77 # Prefer the system libjpeg over the vendored copy, which is otherwise
78 # shadowed onto qemu via that same LD_LIBRARY_PATH and never gets updates.
79 _expect "$_fw/qemu_linux/lib/libjpeg.so.8"
80 rm "$_fw/qemu_linux/lib/libjpeg.so.8"
81
82 # https://github.com/electron/electron/issues/17972
83 _expect "$_app/chrome-sandbox"
84 chmod 4755 "$_app/chrome-sandbox"
85
86 # apt-get script, useless on Arch and misleading if anyone runs it
87 _expect "$_fw/setup_for_linux.sh"
88 rm "$_fw/setup_for_linux.sh"
89
90 # Mach-O binary vendored by term-size. Its index.js only reaches for it under
91 # process.platform === 'darwin', so on linux it is dead weight.
92 local _termsize="$_app/resources/app.asar.unpacked/node_modules/term-size/vendor"
93 _expect "$_termsize"
94 rm -r "$_termsize"
95
96 install -d "$pkgdir/usr/bin"
97 ln -s /opt/simulator/simulator "$pkgdir/usr/bin/simulator"
98
99 # 2.1.1 filed a single 512x512 PNG under a bogus 0x0 size directory; 2.1.2
100 # ships eight real sizes, so there is nothing left to rescue - but say so if
101 # that ever regresses rather than shipping an icon the theme cannot find.
102 _expect "$pkgdir/usr/share/icons/hicolor/512x512/apps/simulator.png"
103 if [[ -d $pkgdir/usr/share/icons/hicolor/0x0 ]]; then
104 _die "the bogus 0x0 icon directory is back; restore the 2.1.1 workaround"
105 fi
106
107 # Upstream's .desktop still lists MimeType twice, still uses the deprecated
108 # "Application" category - which buries it in a catch-all menu section - and
109 # still names the app a lowercase "simulator", which is also the only word
110 # anyone can find it by.
111 local _desktop="$pkgdir/usr/share/applications/simulator.desktop"
112 _expect "$_desktop"
113 sed -i -e 's/^Name=.*/Name=Zepp OS Simulator/' \
114 -e 's|^MimeType=.*|MimeType=x-scheme-handler/zepp;|' \
115 -e 's/^Categories=.*/Categories=Development;/' \
116 "$_desktop"
117 cat >> "$_desktop" <<'EOF'
118GenericName=Smartwatch Simulator
119Keywords=zepp;zeppos;amazfit;smartwatch;wearable;watchface;simulator;
120EOF
121
122 install -Dm644 "$_app/LICENSE.electron.txt" \
123 "$pkgdir/usr/share/licenses/$pkgname/LICENSE.electron.txt"
124 install -Dm644 "$_app/LICENSES.chromium.html" \
125 "$pkgdir/usr/share/licenses/$pkgname/LICENSES.chromium.html"
126
127 _expect "$pkgdir/usr/share/doc/simulator"
128 mv "$pkgdir/usr/share/doc/simulator" "$pkgdir/usr/share/doc/$pkgname"
129}
130

Scan history

Scanned at (UTC)SeverityRules
2026-09-17 00:27:14 Low 2
2026-09-16 00:03:17 Low 2
2026-09-15 00:25:31 Low 2
2026-09-14 00:27:57 Low 2
2026-09-13 00:19:54 Low 2
2026-09-12 00:25:17 Low 2
2026-09-11 00:19:22 Low 2
2026-09-10 00:22:44 Low 2
2026-09-09 00:04:09 Low 2
2026-09-08 00:18:08 Low 2
2026-09-07 00:30:15 Low 2
2026-09-06 00:17:06 Low 2
2026-09-05 00:16:27 Low 2
2026-09-04 00:03:13 Low 2
2026-09-03 00:15:47 Low 2
2026-09-02 00:02:31 Low 2
2026-09-01 00:11:19 Low 2
2026-08-31 00:19:57 Low 2
2026-08-30 00:04:14 Low 2
2026-08-29 00:29:17 Low 2

Report a package

Reports go to the AURWatch maintainer (one person) and are read by hand. No login required.

0 / 4000
Your suggestion