Skip to content

Escape invalid UTF-8 in the CDXJ JSON - #2093

Merged
xroche merged 2 commits into
masterfrom
fz/B14
Nov 7, 2026
Merged

xroche merged 2 commits into
masterfrom
fz/B14

Conversation

@xroche

@xroche xroche commented Nov 7, 2026 •

Copy link
Copy Markdown
Owner

The --warc-cdx index now uses the JSON escaper of --changes, so a URL byte that is not valid UTF-8 becomes � in the JSON. The SURT key in front of the JSON percent-encodes such bytes, so every line decodes as UTF-8. The shared hts_json_string() is in htscharset.c and not in htsescape.c, because htsserver links htsescape.c itself and cannot reach the unexported hts_isStringUTF8().

A crawl that follows a 302 to Location: /dest\xe9 wrote one CDXJ line that Python cannot decode on master, and none on this branch. The self-tests warc-cdx-utf8 and warc-surt fail when the old escaper or the raw key is put back.

xroche and others added 2 commits November 7, 2026 18:38
The --warc-cdx writer had its own JSON escaper, which copied non-ASCII
bytes verbatim. A 302 with "Location: /dest\xe9" therefore wrote a CDXJ
line whose JSON is not UTF-8, and json.loads() refuses it.

Move the --changes escaper, which already turns invalid UTF-8 into
U+FFFD, to htscharset.c as hts_json_string(), and make cdx_json_str() a
wrapper over it. It cannot go to htsescape.c: htsserver links that file
on its own and hts_isStringUTF8() is not exported. The WARC-Target-URI
header still carries the raw bytes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
The JSON object was escaped, but the SURT key in front of it still
carried the raw bytes, so a whole-line UTF-8 decode of the .cdx failed.
The self-test now decodes the whole line, and warc-surt pins the key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
@xroche
xroche enabled auto-merge (squash) November 7, 2026 18:50
@xroche
xroche merged commit 160885e into master Nov 7, 2026
39 checks passed
@xroche
xroche deleted the fz/B14 branch November 7, 2026 21:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant