savestate
Triggered rules
pip_install_external
`pip install <package>` fetches an unpinned package from PyPI at build time, outside source=() and makepkg's checksums.
-
PKGBUILD:61
pip install -r requirements.txt
llm_review
An AI model (anthropic/claude-4.6-sonnet-20260217) reviewed this and agrees it is MEDIUM (confidence 72%): The PKGBUILD uses PyInstaller to bundle a Python application into a single binary, which is a legitimate packaging approach. However, there are genuine supply-chain concerns: (1) The .spec file is pulled from the HEAD of the main branch (not pinned to the tagged release), meaning it can change at any time without the sha256sum catching it — though it does have a checksum, that checksum will become stale if the branch HEAD changes. (2) pip install -r requirements.txt inside a venv installs PyPI packages whose versions are not pinned in the PKGBUILD itself; the requirements.patch modifies requirements.txt but we cannot see what it does. If requirements.txt lacks pinned versions, arbitrary PyPI package versions could be installed at build time and bundled into the final binary. (3) The final installed artifact is a PyInstaller-bundled binary (dist/SaveState) that contains all bundled Python dependencies — users get an opaque binary rather than inspectable Python code. These are real supply-chain concerns (unpinned transitive dependencies from PyPI bundled into an executed binary, plus a floating branch reference for the spec file), consistent with a MEDIUM rating. There is no evidence of active malice or obfuscation.
PKGBUILD
1 offending line(s) highlighted# Maintainer: Mambuco <gabriele.giambrone@icloud.com>
pkgname=savestate
pkgver=2.4B
pkgrel=1
epoch=
pkgdesc="A versatile game save backup manager, featuring Steam detection, Minecraft support, drag & drop, desktop shortcuts and emulator compatible."
arch=('x86_64')
url="https://github.com/Matteo842/SaveState"
license=('GPL-3.0-only')
groups=()
depends=('glibc' 'zlib')
makedepends=('gendesk' 'python>=3.3' 'tk' 'pyside6' 'python-requests' 'python-psutil')
checkdepends=()
optdepends=()
provides=(savestate)
conflicts=(savestate)
replaces=()
backup=()
options=()
install=
changelog=
source=(
"$pkgname-$pkgver.tar.gz::https://github.com/Matteo842/SaveState/archive/refs/tags/v$pkgver.tar.gz"
"SaveState.png::https://github.com/Matteo842/SaveState/blob/v$pkgver/icon.png?raw=true"
"SaveState-OneFile-Linux.spec::https://github.com/Matteo842/SaveState/raw/refs/heads/main/SaveState-OneFile-Linux.spec"
"requirements.patch"
)
noextract=()
sha256sums=(
'6af640adf6ce0fc326f29be23a0212072d698c23003baf35a01e18c67c5c7b22'
'7f7b294aa10ef51f23dbccd814e2ce507269be889e444f2bf2b1fb5c50dcb15e'
'ac19894ca894e119940a48ec62f51f25c8c8623e433f60d52fee8863a0c4fd61'
'30e31c8e0e980dbf7726e09e555f1aba339326daf67cc544f230084adf4cea76'
)
validpgpkeys=()
_name="SaveState"
_categories=('Game;Utility')
_exec="/usr/bin/SaveState"
prepare() {
cd "$srcdir"
# Generate .desktop file
echo "Generating .desktop file..."
gendesk --pkgname="$pkgname" --pkgdesc="$pkgdesc" \
--categories=$_categories \
--name=$_name \
--genericname=$_name \
--exec=$_exec \
--icon=$_name \
-f
cd "$_name-$pkgver"
patch -p1 -i ../requirements.patch
python -m venv ./venv
source ./venv/bin/activate
pip install -r requirements.txt
}
build() {
cd "$srcdir/$_name-$pkgver"
source ./venv/bin/activate
# TODO: Remove on next release
cp ../SaveState-OneFile-Linux.spec .
pyinstaller --clean SaveState-OneFile-Linux.spec
}
package() {
cd "$srcdir"
install -Dm0755 -t "$pkgdir/usr/share/applications/" "savestate.desktop"
install -Dm0755 -t "$pkgdir/usr/share/icons/" "$_name.png"
install -Dm0755 -t "$pkgdir/usr/bin" "$_name-$pkgver/dist/SaveState"
}
Scan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 2026-08-03 00:08:14 | MEDIUM | 2 |
| 2026-08-02 00:16:08 | MEDIUM | 2 |
| 2026-08-01 00:11:18 | MEDIUM | 2 |
| 2026-07-31 00:14:10 | MEDIUM | 2 |
| 2026-07-30 00:17:23 | MEDIUM | 2 |
| 2026-07-29 00:25:53 | MEDIUM | 2 |
| 2026-07-28 00:07:28 | MEDIUM | 2 |
| 2026-07-27 00:24:32 | MEDIUM | 2 |
| 2026-07-26 00:07:32 | MEDIUM | 2 |
| 2026-07-25 00:13:44 | MEDIUM | 2 |
| 2026-07-24 00:02:28 | MEDIUM | 2 |
| 2026-07-23 00:14:47 | MEDIUM | 2 |
| 2026-07-22 00:29:32 | MEDIUM | 2 |
| 2026-07-21 00:24:15 | MEDIUM | 2 |
| 2026-07-20 00:19:49 | MEDIUM | 2 |
| 2026-07-19 00:17:08 | MEDIUM | 2 |
| 2026-07-18 00:14:48 | MEDIUM | 2 |
| 2026-07-17 00:06:16 | MEDIUM | 2 |
| 2026-07-16 00:05:41 | MEDIUM | 2 |
| 2026-07-15 00:09:25 | MEDIUM | 2 |