Skip to content

Commit 164a0c3

Browse files
authored
Merge pull request #342 from rmz-oz/fix-encoded-hash-in-document-uri
Keep encoded # in ZIM paths when building document URIs
2 parents 7908b7b + 5ecd60b commit 164a0c3

3 files changed

Lines changed: 37 additions & 1 deletion

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
- Carry a script's top-level `const`, `let` and `class` declarations across the wombat block, so other scripts on the page can still see them (#329)
1313
- Keep a rewritten `<script>`'s original `src` in `__wb_orig_src`, so wombat can return it from `getAttribute("src")` and bundlers that identify chunks by it (Next.js/Turbopack, Vite) still work (openzim/warc2zim#473)
14+
- Keep URL-encoded `#` characters of the path or querystring when rewriting document URIs, instead of dropping everything after them (#341)
1415

1516
## [5.4.1] - 2026-07-31
1617

‎src/zimscraperlib/rewriting/url_rewriting.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,9 @@ def get_document_uri(self, item_path: ZimPath, item_fragment: str) -> str:
312312
URI.
313313
314314
"""
315-
item_parts = urlsplit(item_path.value)
315+
# a ZIM path is never URL-encoded, so a `#` in it is a literal character
316+
# (e.g. coming from a `%23` in original URL) and not a fragment delimiter
317+
item_parts = urlsplit(item_path.value, allow_fragments=False)
316318

317319
# item_path is both path + querystring, both will be url-encoded in the document
318320
# so that readers consider them as a whole and properly pass them to libzim

‎tests/rewriting/test_url_rewriting.py‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,39 @@ def test_missing_zim_paths(
206206
["kiwix.org/a/article/foo.html?foo=b?ar"],
207207
False,
208208
),
209+
(
210+
"https://kiwix.org/a/article/document.html",
211+
"foo%23bar.html", # a path with an encoded # char
212+
RewriteResult(
213+
"https://kiwix.org/a/article/foo%23bar.html",
214+
"foo%23bar.html",
215+
ZimPath("kiwix.org/a/article/foo#bar.html"),
216+
),
217+
["kiwix.org/a/article/foo#bar.html"],
218+
False,
219+
),
220+
(
221+
"https://kiwix.org/a/article/document.html",
222+
"foo%23bar.html#anchor1", # encoded # char followed by a fragment
223+
RewriteResult(
224+
"https://kiwix.org/a/article/foo%23bar.html#anchor1",
225+
"foo%23bar.html#anchor1",
226+
ZimPath("kiwix.org/a/article/foo#bar.html"),
227+
),
228+
["kiwix.org/a/article/foo#bar.html"],
229+
False,
230+
),
231+
(
232+
"https://kiwix.org/a/article/document.html",
233+
"foo.html?foo=b%23ar", # a query string with an encoded # char
234+
RewriteResult(
235+
"https://kiwix.org/a/article/foo.html?foo=b%23ar",
236+
"foo.html%3Ffoo=b%23ar",
237+
ZimPath("kiwix.org/a/article/foo.html?foo=b#ar"),
238+
),
239+
["kiwix.org/a/article/foo.html?foo=b#ar"],
240+
False,
241+
),
209242
(
210243
"https://kiwix.org/a/article/document.html",
211244
"fo%o.html",

0 commit comments

Comments
 (0)