Conversation
…accepts
generate_filename() derived a name from the Telegraph API's page.path and replaced
only a shell-safety set (/ \ : ? * " < > |). The read side goes through
is_valid_post_id(), which accepts only [A-Za-z0-9_-], so a path containing any
other character produced a file that was written successfully and then never
served:
"a/../../etc/passwd" -> "a-..-..-etc-passwd.md" (unreadable)
"..\\..\\win" -> "--..-win.md" (unreadable)
".env" -> ".env.md" (hidden, unreadable)
"" / "." / ".." -> ".md" / "..md" (hidden, empty id)
400-char path -> 400-char stem (over MAX_POST_ID_LEN)
is_valid_post_id()'s doc comment asserted that "the Telegraph archiver yields
[A-Za-z0-9_-] slugs"; it did not.
Apply the reader's charset on the write side: map anything outside [A-Za-z0-9_-]
to '-', collapse runs, trim the ends, fall back to a fixed name for a degenerate
path, and bound the stem to leave room for the extension. Written and servable
are now the same set by construction.
The cost is that a non-ASCII path segment is dropped ("unicode-日本語-ページ"
becomes "unicode.md"); it replaces a name the reader could never accept at all.
Verified: cargo test is 149 passed / 0 failed. Against the unpatched source the
new suite fails 4 of 7, including the contract assertion that every produced
filename satisfies is_valid_post_id.
Closes #34
Author
|
One note on CI: the I ran the suite locally on this branch before opening the PR, and again after reverting only the
Happy to adjust if the fallback name or the length bound should be different. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #34
What
generate_filename()derived a name from the Telegraph API'spage.pathand replaced only ashell-safety set (
/ \ : ? * " < > |). The matching read goes throughis_valid_post_id(),which accepts only ASCII alphanumerics,
-and_. Any other character therefore produced a filethat was written successfully and then never served:
patha/../../etc/passwda-..-..-etc-passwd.md.rejected)..\..\win--..-win.md.env.env.md"",".","..".md,..mdMAX_POST_ID_LEN)is_valid_post_id()'s doc comment asserted the invariant that was violated -- that "the Telegrapharchiver yields
[A-Za-z0-9_-]slugs". It did not.How
Apply the reader's character set on the write side: map everything outside
[A-Za-z0-9_-]to-,collapse runs, trim the ends, fall back to
untitledfor a degenerate path, and bound the stem to250 bytes so
MAX_POST_ID_LEN(255) still holds once.mdis appended. Written and servable arenow the same set by construction, which is the property the new tests assert.
Also corrected the
is_valid_post_id()doc comment and noted why the write side has to satisfy thesame gate.
Deliberate behaviour change: a path with non-ASCII segments loses them --
unicode-日本語-ページbecomesunicode.md. That is the price of a name the reader accepts, and itreplaces a name the reader could never accept at all; the test comment says so explicitly.
Verification
cargo teston the patched tree:archiver module only:
The same suite against the unpatched implementation (tests kept, implementation reverted):
The tests assert the contract, not a character list:
is_valid_post_idbecomespub(crate)so the archiver's tests can assert against the real gaterather than a copy of it. I also verified the mapping by exhaustive and randomised enumeration
outside the suite (all 1,464 combinations up to length 3 of
./\: -_a0?*, then 20,000 randomprintable-ASCII strings): no output was ever rejected by the gate or started with
., and the stemstayed within the bound for inputs up to 5,000 characters.
Related
Adjacent to but not the same as #27 / #28: that was the read route interpolating an unvalidated id
into a path. This is the write route producing a name the read gate rejects. The existing
separator replacement already prevents traversal, and the new mapping keeps that true.
I did not add a Monero address to any comment; if a bounty applies, any address convenient to you is
fine, and no payment is expected if this does not meet the bar.