aio-libs / aio-libs/yarl

URL.join() decodes percent-encoded characters in the base path (e.g. %2F becomes /)

Offen
#1,774 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
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

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.