URL.join() decodes percent-encoded characters in the base path (e.g. %2F becomes /)
- Vorherrschende Sprache
- Python
- Sterne
- 1.5k
- Forks
- 215
- Ø Merge
- 1 T. 2 Min.
- Gemergte PRs (30 T.)
- 13
Beschreibung
### Description
`URL.join()` decodes percent-encoded characters in the base URL's path when merging a relative reference (RFC 3986 §5.3, the branch used when the base path does not end with `/`). The merge is built from `self.parts`, which are already percent-decoded, so an encoded delimiter like `%2F` is turned into a real `/` and the path structure is corrupted.
### Reproduction
```python
from yarl import URL
print(URL("http://x/a%2Fb/c").join(URL("d"))) # http://x/a/b/d
print(URL("http://x/a%20b/c").join(URL("d"))) # http://x/a b/d
```
### Expected vs actual
| | result |
|---|---|
| expected | `http://x/a%2Fb/d` (the `a%2Fb` segment is preserved) |
| actual | `http://x/a/b/d` (`%2F` decoded into a separator -> the single segment splits into two) |
`%20` is likewise decoded into a literal space.
### Root cause
The RFC-3986 merge branch in `URL.join` constructs the merged path from `self.parts[:-1]`. `parts` runs the segments through `UNQUOTER` (decoded), so feeding them back into a path mixes decoded text with the still-encoded relative path. The raw/encoded segments (`raw_parts`) should be used for the merge so the original encoding round-trips.
(Distinct from #896, which is RFC-correct last-segment replacement; this is specifically the loss of percent-encoding.)
Beitragsleitfaden
Bewertung
Dieses Issue wurde noch nicht bewertet.