mirror of
https://github.com/xroche/httrack.git
synced 2026-08-07 08:17:30 +03:00
* Bound the ProxyTrack DAV item buffer against an amplified PROPFIND path proxytrack_add_DAV_Item() reserved a fixed 1024 bytes and then sprintf'd into it unbounded. The request path lands in the response twice, once as the href and once as the displayname, and escapexml() turns each '&' into '&', so an unauthenticated PROPFIND of roughly 900 ampersands writes about 9000 bytes off the end of the heap block. No cache entry and no Depth: 1 are needed. Replace the hand-sized reserve with StringSprintf(), which measures the formatted output and grows the String to fit, and convert the sibling sprintf sites in the same file so no unbounded write into a String is left to re-audit. Sizing beats clipping here: the String already owns a growable buffer, so nothing has to be dropped. Closes #836 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Xavier Roche <roche@httrack.com> * Bound StringSprintf's pre-C99 retry, and trim the review findings A genuine vsnprintf conversion error returns -1 just as pre-C99 msvcrt does for a short buffer, so the doubling search had no way to tell them apart and grew until realloc aborted. Unreachable from these format strings, which use only %s and %d, but the helper lives in a shared header and will get more callers. Cap the search and empty the String past it. Also: the count assertion piped into wc under pipefail, so a zero count killed the test through set -e before its diagnostic could print. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Xavier Roche <roche@httrack.com> * Lift the NO_WEBDAV conditional out of a macro argument list A preprocessor directive inside a macro invocation's arguments is undefined: it was fine while this was a plain sprintf() call, and MSVC rejected it as soon as it became StringSprintf(). GCC accepts it, so only the Windows leg caught it. Compute the DAV header fragment first and pass it as an argument. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Xavier Roche <roche@httrack.com> * Cover StringSprintf's exact-fill case and the WebDAV enumeration branch StringSprintf_ writes the terminator at buffer[ret], so widening its `ret < capacity` guard by one byte is a heap overflow that only fires when the formatted output exactly fills the capacity. No crawl test lands on a capacity boundary, so the mutant survived the suite. The new `strsprintf` self-test sweeps lengths around 256, 512, 1024 and 2048 with the String's capacity pinned to each, plus a growing and shrinking sweep on one reused String, and checks the length, the bytes and the terminator every time. Test 147 only ever sent Depth: 0, leaving the enumeration branch the same PR rewrote with no coverage at all. Its fixture gains a child directory, and a Depth: 1 listing pins the item URLs, including the trailing '/' that StringPopRight takes back off a directory name. Signed-off-by: Xavier Roche <xroche@gmail.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Xavier Roche <roche@httrack.com> * Declare the new WebDAV test in the Windows skip set It skips on Windows for the same reason as its two neighbours, MSYS cannot reap a background listener (#595), and the ratchet fails a skip it was not told about. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0199wAkSVZNBNp51mpRkxMvv Signed-off-by: Xavier Roche <roche@httrack.com> --------- Signed-off-by: Xavier Roche <roche@httrack.com> Signed-off-by: Xavier Roche <xroche@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
26 lines
690 B
Bash
Executable File
26 lines
690 B
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# StringSprintf writes the terminator at buffer[ret], so a `ret <= capacity`
|
|
# guard overflows by one byte whenever the output exactly fills the capacity
|
|
# (#836). The proxytrack crawl tests never land on a capacity boundary.
|
|
|
|
set -euo pipefail
|
|
|
|
: "${top_srcdir:=..}"
|
|
|
|
# Resolve httrack before any cd: PATH may carry a build-relative entry.
|
|
bin=$(command -v httrack) || {
|
|
echo "FAIL: httrack not found on PATH" >&2
|
|
exit 1
|
|
}
|
|
|
|
fail() {
|
|
echo "FAIL: $1" >&2
|
|
exit 1
|
|
}
|
|
|
|
out=$("$bin" -#test=strsprintf) || fail "httrack -#test=strsprintf exited non-zero: $out"
|
|
test "$out" = "strsprintf self-test: OK" || fail "expected 'strsprintf self-test: OK', got: $out"
|
|
|
|
exit 0
|