Skip to content

fix: decode percent-encoded unreserved chars before resolving dot segments in normalize - #195

Open
binggao1230 wants to merge 1 commit into
python-hyper:masterfrom
binggao1230:fix-normalize-percent-encoded-dots
Open

fix: decode percent-encoded unreserved chars before resolving dot segments in normalize#195
binggao1230 wants to merge 1 commit into
python-hyper:masterfrom
binggao1230:fix-normalize-percent-encoded-dots

Conversation

@binggao1230

Copy link
Copy Markdown

Summary

URL.normalize() resolves dot segments (. and ..) before decoding percent-encoded unreserved characters. Per RFC 3986 Section 6.2.2.2, this order is incorrect -- unreserved characters should be decoded first.

For example, %2e is the percent-encoded form of . (a period is an unreserved character). The path /%2e%2e/foo should be normalized to /foo, but currently it normalizes to /../foo.

Before

>>> URL.from_text("http://example.com/%2e%2e/foo").normalize().to_text()
'http://example.com/../foo'

After

>>> URL.from_text("http://example.com/%2e%2e/foo").normalize().to_text()
'http://example.com/foo'

Test plan

  • Added test_normalize_percent_encoded_dot_segments covering three cases:
    • %2e%2e (double-dot parent reference)
    • %2e (single-dot current directory reference)
    • foo/%2e%2e/bar (encoded parent traversal in middle of path)
  • All 102 tests pass (101 existing + 1 new)

This PR was written under human direction (gaoflow).

…ments in normalize

RFC 3986 Section 6.2.2.2 specifies that percent-encoded unreserved
characters should be decoded before applying other normalizations,
including dot-segment resolution. The previous order (resolve-then-decode)
meant that %2e%2e was not recognized as ".." during path normalization,
producing incorrect results like http://example.com/../foo instead of
http://example.com/foo.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant