release: restore ZUPT and harden source-only 5.2.2

This commit is contained in:
Cristian Cezar Moisés 2026-08-31 14:14:36 -03:00
commit ff99770bd0
205 changed files with 19627 additions and 13215 deletions

View file

@ -0,0 +1,85 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-or-later
# Copyright (c) 2026 Cristian Cezar Moisés
# A signal received while a password is read must not leave terminal echo off.
set -Eeuo pipefail
bin=${1:-./zupt}
if [[ ! -x $bin ]]; then
printf 'FAIL: ZUPT binary is not executable: %s\n' "$bin" >&2
exit 1
fi
case $(uname -s) in
MINGW*|MSYS*|CYGWIN*)
printf '%s\n' \
'SKIP: POSIX pseudo-terminal signal restoration test is unavailable on Windows'
exit 0
;;
esac
if ! command -v python3 >/dev/null 2>&1; then
printf 'SKIP: password-prompt signal test needs python3 with pty support\n'
exit 0
fi
bin=$(cd "$(dirname "$bin")" && pwd -P)/$(basename "$bin")
python3 - "$bin" <<'PY'
import os
import pty
import select
import signal
import subprocess
import tempfile
import termios
import time
import sys
binary = sys.argv[1]
with tempfile.TemporaryDirectory(prefix="zupt-password-signal-") as work:
source = os.path.join(work, "input.txt")
archive = os.path.join(work, "interrupted.zupt")
with open(source, "w", encoding="utf-8") as stream:
stream.write("terminal restoration regression\n")
master, slave = pty.openpty()
initial = termios.tcgetattr(slave)
process = subprocess.Popen(
[binary, "compress", "--password-prompt", archive, source],
stdin=slave,
stdout=slave,
stderr=slave,
close_fds=True,
)
transcript = bytearray()
deadline = time.monotonic() + 10
try:
while b"Password:" not in transcript and time.monotonic() < deadline:
readable, _, _ = select.select([master], [], [], 0.1)
if readable:
transcript.extend(os.read(master, 4096))
if process.poll() is not None:
break
if b"Password:" not in transcript:
raise SystemExit("password prompt was not reached")
hidden = termios.tcgetattr(slave)
if hidden[3] & termios.ECHO:
raise SystemExit("terminal echo was not disabled during prompt")
process.send_signal(signal.SIGINT)
process.wait(timeout=10)
restored = termios.tcgetattr(slave)
if (restored[3] & termios.ECHO) != (initial[3] & termios.ECHO):
raise SystemExit("terminal echo state was not restored after SIGINT")
if not (restored[3] & termios.ECHO):
raise SystemExit("terminal echo is disabled after interrupted prompt")
if os.path.exists(archive):
raise SystemExit("interrupted password prompt left an archive")
finally:
if process.poll() is None:
process.kill()
process.wait()
os.close(master)
os.close(slave)
print("password prompt signal restoration: PASS")
PY