fix: implement rfc3986 dot-segment removal and percent-encoding normalization - #152
Open
gaoflow wants to merge 1 commit into
Open
Conversation
…lization
resolve() and normalize() each carried their own hand-written "." / ".."
loop, and neither was the remove_dot_segments routine from rfc3986 section
5.2.4. Both now call one helper transcribed from it.
- A trailing "." or ".." segment lost the "/" that steps 2B and 2C leave
behind, so resolve('http://a/b/c/d;p?q', '..') returned 'http://a/b'.
- A reference with its own authority inherited the base path and port.
Section 5.2.2 does not consult the base when R.authority is defined, and
the section 5.4.1 table gives "//g" = "http://g".
- normalize() ran rawurlencode(rawurldecode($segment)), which escapes the
sub-delims plus ":" and "@" even though all of them are valid pchar
(section 3.3). Section 2.2 protects reserved characters from
normalization, so this reported /a;b and /a%3Bb as equal. Its ltrim() and
unconditional '/'.implode() also collapsed empty segments and rooted
rootless paths.
The rfc3986 section 5.4.1 and 5.4.2 examples are now a data provider.
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.
resolve()andnormalize()each carried their own hand-written./..loop, and neither is theremove_dot_segmentsroutine from rfc3986 §5.2.4. Both now call one helper transcribed from it.A trailing
.or..segment dropped the required slash — §5.2.4 steps 2B/2C replace a final/.or/..with/.resolve('http://a/b/c/d;p?q', '..')returnedhttp://a/b, wanthttp://a/b/;normalize('http://e.org/a/b/..')returnedhttp://e.org/a, wanthttp://e.org/a/.A reference with its own authority inherited the base path and port — §5.2.2 does not consult the base when
R.authorityis defined.resolve('http://a/b/c/d;p?q', '//g')returnedhttp://g/b/c/d;p, but the §5.4.1 table in the RFC gives"//g" = "http://g".resolve('https://a:8080/x/y', '//g/h')returnedhttps://g:8080/h, wanthttps://g/h.normalize()percent-encoded valid path characters —rawurlencode(rawurldecode($segment))escapes the 11 sub-delims plus:and@, all of which are validpchar(§3.3), sohttp://a/b/c/d;p?qbecamehttp://a/b/c/d%3Bp?qand/a;bcompared equal to/a%3Bb, which §2.2 says are not equivalent. Theltrim()also collapsed//ato/aand the unconditional'/'.implode()rooted rootless paths (urn:isbn:0451450523→urn:/isbn%3A0451450523). Triplets are now upper-cased and decoded only when the octet is unreserved (§6.2.2.1, §6.2.2.2); bytes that are notpcharare still encoded, as before.The §5.4.1 and §5.4.2 examples are now a data provider — 41 of the 42, with the empty reference left out because #145 covers it. Plus normalization vectors for the 13 characters, the trailing dot segments,
%2E, empty segments and rootless paths.Four
ResolveTestrows change, all of them//example.netwith no path. They arrived in 0d4c9a3 next to a?:→??falsiness fix for a base path of'0', and they pin the base-path inheritance above; the four sibling rows using//example.net/are untouched, and I added two rows so a'0'base path stays covered. Cross-checked againsturllib.parse.urljoin, Gonet/urland Addressable — all three drop the base path for//g. phpunit, phpstan and php-cs-fixer are green locally.