release: prepare ZUPT 5.2.6 native gates

This commit is contained in:
Cristian Cezar Moisés 2026-08-31 18:12:27 -03:00
commit 7821523942
31 changed files with 418 additions and 207 deletions

View file

@ -42,6 +42,31 @@ static size_t put_varint(uint8_t *out, uint64_t value) {
return count;
}
static int hex_nibble(unsigned char value) {
if (value >= '0' && value <= '9') return (int)(value - '0');
if (value >= 'a' && value <= 'f') return (int)(value - 'a') + 10;
if (value >= 'A' && value <= 'F') return (int)(value - 'A') + 10;
return -1;
}
static int decode_hex_entry(const char *hex, uint8_t *out, size_t capacity,
size_t *out_size) {
size_t hex_size = strlen(hex);
if (hex_size == 0 || (hex_size & 1u) != 0 ||
hex_size / 2u >= capacity)
return -1;
size_t decoded_size = hex_size / 2u;
for (size_t i = 0; i < decoded_size; i++) {
int high = hex_nibble((unsigned char)hex[i * 2u]);
int low = hex_nibble((unsigned char)hex[i * 2u + 1u]);
if (high < 0 || low < 0) return -1;
out[i] = (uint8_t)((high << 4) | low);
}
*out_size = decoded_size;
return 0;
}
static int write_block(FILE *stream, uint8_t type, const uint8_t *payload,
size_t payload_size, uint64_t unpacked_size,
uint64_t checksum) {
@ -66,11 +91,24 @@ static int write_block(FILE *stream, uint8_t type, const uint8_t *payload,
int main(int argc, char **argv) {
static const uint8_t content[] = "fixture content\n";
const char *entry = argc == 3 && strncmp(argv[2], "--entry=", 8) == 0
? argv[2] + 8 : NULL;
if (!entry || argv[1][0] == '\0' || entry[0] == '\0' ||
strlen(entry) >= ZUPT_MAX_PATH) {
fprintf(stderr, "usage: %s ARCHIVE --entry=ENTRY_PATH\n", argv[0]);
uint8_t decoded_entry[ZUPT_MAX_PATH];
const uint8_t *entry = NULL;
size_t path_size = 0;
if (argc == 3 && strncmp(argv[2], "--entry=", 8) == 0) {
entry = (const uint8_t *)argv[2] + 8;
path_size = strlen(argv[2] + 8);
} else if (argc == 3 &&
strncmp(argv[2], "--entry-hex=", 12) == 0 &&
decode_hex_entry(argv[2] + 12, decoded_entry,
sizeof(decoded_entry), &path_size) == 0) {
entry = decoded_entry;
}
if (!entry || argv[1][0] == '\0' || path_size == 0 ||
path_size >= ZUPT_MAX_PATH) {
fprintf(stderr,
"usage: %s ARCHIVE --entry=ENTRY_PATH|--entry-hex=HEX_BYTES\n",
argv[0]);
return 2;
}
@ -106,7 +144,6 @@ int main(int argc, char **argv) {
uint8_t index[ZUPT_MAX_PATH + 128];
size_t index_size = 0;
size_t path_size = strlen(entry);
index_size += put_varint(index + index_size, 1);
index_size += put_varint(index + index_size, path_size);
memcpy(index + index_size, entry, path_size);

View file

@ -104,33 +104,62 @@ else
fail 'control-byte archive path is rejected without terminal injection'
fi
expect_display_unsafe_path_rejected() {
local label=$1 name=$2 entry=$3
file_contains_hex_bytes() {
python3 - "$1" "$2" <<'PY'
import pathlib
import sys
data = pathlib.Path(sys.argv[1]).read_bytes()
needle = bytes.fromhex(sys.argv[2])
raise SystemExit(0 if needle in data else 1)
PY
}
expect_display_unsafe_hex_path_rejected() {
local label=$1 name=$2 entry_hex=$3 forbidden_hex=$4
local archive=$TEST_ROOT/$name.zupt log=$TEST_ROOT/$name.log status
MSYS2_ARG_CONV_EXCL='--entry=' "$FIXTURE" "$archive" "--entry=$entry"
MSYS2_ARG_CONV_EXCL='--entry-hex=' \
"$FIXTURE" "$archive" "--entry-hex=$entry_hex"
if ! file_contains_hex_bytes "$archive" "$entry_hex"; then
printf ' fixture did not preserve the requested path bytes: %s\n' \
"$entry_hex" >&2
fail "$label"
return
fi
set +e
"$ZUPT_BIN" list "$archive" > "$log" 2>&1
status=$?
set -e
if ((status != 0)) && ! LC_ALL=C grep -Fq -- "$entry" "$log"; then
if ((status != 0)) && ! file_contains_hex_bytes "$log" "$forbidden_hex"; then
pass "$label"
else
fail "$label"
fi
}
expect_display_unsafe_path_rejected \
if MSYS2_ARG_CONV_EXCL='--entry-hex=' \
"$FIXTURE" "$TEST_ROOT/invalid-hex.zupt" '--entry-hex=0' \
>/dev/null 2>&1 ||
MSYS2_ARG_CONV_EXCL='--entry-hex=' \
"$FIXTURE" "$TEST_ROOT/invalid-hex.zupt" '--entry-hex=GG' \
>/dev/null 2>&1; then
fail 'archive path fixture rejects malformed hex input'
else
pass 'archive path fixture rejects malformed hex input'
fi
expect_display_unsafe_hex_path_rejected \
'raw C1 archive path is rejected without terminal injection' \
raw-c1 $'safe\23331m.txt'
expect_display_unsafe_path_rejected \
raw-c1 736166659b33316d2e747874 9b
expect_display_unsafe_hex_path_rejected \
'UTF-8 C1 archive path is rejected without terminal injection' \
utf8-c1 $'safe\302\23331m.txt'
expect_display_unsafe_path_rejected \
utf8-c1 73616665c29b33316d2e747874 c29b
expect_display_unsafe_hex_path_rejected \
'Unicode bidi-control archive path is rejected without display spoofing' \
bidi $'safe\342\200\256exe.txt'
expect_display_unsafe_path_rejected \
bidi 73616665e280ae6578652e747874 e280ae
expect_display_unsafe_hex_path_rejected \
'invalid UTF-8 archive path is rejected without raw display' \
invalid-utf8 $'safe\300\257.txt'
invalid-utf8 73616665c0af2e747874 c0af
make_fixture "$TEST_ROOT/leaf.zupt" 'innocent.txt'
printf '%s\n' DO_NOT_OVERWRITE > "$TEST_ROOT/sentinel"