fthr-clips-bin

LOW
maintainer Ransom 0 votes scanned 2026-09-18 21:28:57.026605
View on AUR
Why flagged

The package installs an official AppImage from the project's GitHub release page, which is unpacked and verified without executing arbitrary remote code; the low severity is due to the unverifiable binary nature of the AppImage and SKIP'd checksums, but it comes from a legitimate project source.

Triggered rules

Low Few votes, recently uploaded zero_votes_recent

Uploaded within the last 14 days with 2 or fewer community votes — little peer review so far.

Low AI review llm_review

An AI model (qwen/qwen3-235b-a22b-2507) reviewed this and agrees it is LOW (confidence 90%): The package installs an official AppImage from the project's GitHub release page, which is unpacked and verified without executing arbitrary remote code; the low severity is due to the unverifiable binary nature of the AppImage and SKIP'd checksums, but it comes from a legitimate project source.

PKGBUILD

1# Maintainer: Vaspyyy <lolbautz2 at gmail dot com>
2pkgname=fthr-clips-bin
3pkgver=1.1.0alpha
4pkgrel=2
5_upstream_version=1.1.0-alpha
6pkgdesc='Instant replay capture and clip management (official Linux binary)'
7arch=('x86_64')
8url='https://github.com/FTHR-Community/FTHR-Clips'
9license=('GPL-3.0-only' 'MIT')
10depends=('glibc' 'zlib' 'libglvnd' 'libdrm' 'libxcb' 'wayland')
11makedepends=('python' 'squashfs-tools')
12optdepends=(
13 'pipewire-pulse: desktop audio through PipeWire'
14 'pulseaudio: alternative desktop audio server'
15 'grim: screenshots on supported Wayland compositors'
16 'openbsd-netcat: compositor hotkey socket commands'
17 'ffmpeg: clip export and video thumbnails'
18 'xorg-xwayland: KDE UI fallback for the upstream native Wayland window bug'
19 'xdg-utils: open the clips folder'
20 'libva-mesa-driver: AMD VA-API encoding'
21 'nvidia-utils: NVIDIA NVENC encoding (upstream unqualified)'
22 'xdotool: X11 window detection'
23 'xorg-xprop: X11 fullscreen detection'
24 'xorg-xrandr: native X11 monitor geometry'
25)
26provides=("fthr-clips=$pkgver")
27conflicts=('fthr-clips')
28options=('!strip' '!debug')
29source=("FTHRClips-${_upstream_version}-x86_64.AppImage::https://github.com/FTHR-Community/FTHR-Clips/releases/download/v${_upstream_version}/FTHRClips-${_upstream_version}-x86_64.AppImage")
30noextract=("FTHRClips-${_upstream_version}-x86_64.AppImage")
31sha256sums=('47634819ac68e797ca42e76c9d1fe9f465d817f937a177d75733f4a591086b1a')
32
33prepare() {
34 # Read the ELF boundary without executing the downloaded AppImage runtime.
35 local _offset
36 _offset=$(python - "${noextract[0]}" <<'PY'
37import struct, sys
38with open(sys.argv[1], 'rb') as f:
39 header = f.read(64)
40 assert header[:6] == b'\x7fELF\x02\x01' and header[8:11] == b'AI\x02'
41 offset = struct.unpack_from('<Q', header, 40)[0]
42 size, count = struct.unpack_from('<HH', header, 58)
43 offset += size * count
44 f.seek(offset)
45 assert f.read(4) == b'hsqs', 'AppImage layout changed; review required'
46 print(offset)
47PY
48 )
49 rm -rf squashfs-root
50 unsquashfs -no-progress -d squashfs-root -o "$_offset" "${noextract[0]}"
51 # Fail closed on launcher/layout changes: a new release needs review.
52 echo '943c78b5fd42cf82c035365c24c97faf81736a3959f0b68d1aa7d17621061c0c squashfs-root/AppRun' | sha256sum -c -
53 python - <<'PY'
54from pathlib import Path
55import stat
56root = Path('squashfs-root').resolve()
57assert {p.name for p in root.iterdir()} == {
58 'AppRun', 'FTHRClips', '_internal', 'LICENSE', 'THIRD_PARTY_NOTICES.md',
59 'licenses', 'fthr-clips.desktop', 'fthr-clips.png', '.DirIcon'}
60for name in ('FTHRClips', '_internal/FTHRclips',
61 '_internal/plugin-packages/FTHR-Uploader-linux.fthrplugin',
62 'licenses/MIT.txt', 'licenses/FTHR-GENERATED-ASSETS.txt'):
63 assert (root / name).is_file(), f'Missing upstream component: {name}'
64for p in root.rglob('*'):
65 mode = p.lstat().st_mode
66 assert not mode & 0o6000, f'Privileged permission: {p}'
67 assert stat.S_ISREG(mode) or stat.S_ISDIR(mode) or stat.S_ISLNK(mode), p
68 if p.is_symlink():
69 assert p.resolve().is_relative_to(root) and p.exists(), f'Unsafe symlink: {p}'
70PY
71}
72
73package() {
74 cd squashfs-root
75 install -d "$pkgdir/usr/lib/fthr-clips" "$pkgdir/usr/bin"
76 cp -a FTHRClips _internal "$pkgdir/usr/lib/fthr-clips/"
77 # Preserve PyInstaller's relative runtime tree. Adapt upstream's tiny launcher
78 # for a fixed system location and a stable Qt/Wayland desktop identity.
79 sed -e 's|^HERE=.*|HERE=/usr/lib/fthr-clips|' \
80 -e 's/if \[ -n "${WAYLAND_DISPLAY:-}" \]/if [ -z "${QT_QPA_PLATFORM:-}" ] \&\& [ -n "${WAYLAND_DISPLAY:-}" ]/' \
81 -e 's/elif \[ -n "${DISPLAY:-}" \]/elif [ -z "${QT_QPA_PLATFORM:-}" ] \&\& [ -n "${DISPLAY:-}" ]/' \
82 -e 's|exec "$HERE/FTHRClips"|exec "$HERE/FTHRClips" -desktopfile fthr-clips|' \
83 AppRun > "$pkgdir/usr/bin/fthr-clips"
84 # v1.1.0-alpha has an invisible native KWin window (upstream PR #10).
85 # UI-only fallback: WAYLAND_DISPLAY remains set for the capture engine.
86 sed -i '/^HERE=/a\
87# Remove this KDE fallback after upstream fixes its native Wayland window.\
88if [ -z "${QT_QPA_PLATFORM:-}" ] \&\& [ -n "${WAYLAND_DISPLAY:-}" ]; then\
89 case ":${XDG_CURRENT_DESKTOP:-}:" in\
90 *:KDE:*) export QT_QPA_PLATFORM=xcb ;;\
91 esac\
92fi' "$pkgdir/usr/bin/fthr-clips"
93 chmod 755 "$pkgdir/usr/bin/fthr-clips"
94 install -Dm644 fthr-clips.desktop "$pkgdir/usr/share/applications/fthr-clips.desktop"
95 sed -i -e 's/^Exec=AppRun$/Exec=fthr-clips/' -e 's/^Categories=.*/Categories=AudioVideo;Video;/' -e '/^Icon=/a StartupWMClass=FTHR Clips' "$pkgdir/usr/share/applications/fthr-clips.desktop"
96 install -Dm644 fthr-clips.png "$pkgdir/usr/share/icons/hicolor/512x512/apps/fthr-clips.png"
97 install -d "$pkgdir/usr/share/licenses/$pkgname"
98 cp -a LICENSE THIRD_PARTY_NOTICES.md licenses/. "$pkgdir/usr/share/licenses/$pkgname/"
99 find "$pkgdir" -type d -exec chmod 755 {} +
100 chmod -R a+rX "$pkgdir/usr/lib/fthr-clips" "$pkgdir/usr/share/licenses/$pkgname"
101}
102

Scan history

Scanned at (UTC)SeverityRules
2026-09-18 21:28:57 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