Skip to content

Commit b4322fe

Browse files
committed
LibTextCodec: Fix ISO-2022-JP encoder U+FFFD handling
The jis0208 index contains 0xFFFD placeholder entries for unmapped pointers. The generator-produced inverse accessor would match these when encoding U+FFFD itself, returning a bogus JIS pointer instead of reporting the code point as unmappable. Guard at the call site in the ISO-2022-JP encoder rather than modifying the Python generator, to avoid changing inverse accessors for other indexes (big5, euc_kr, gb18030, etc.) which don't exhibit this bug. This fixes 4 WPT subtests in iso-2022-jp-encoder.html.
1 parent a13017c commit b4322fe

3 files changed

Lines changed: 54 additions & 1 deletion

File tree

Libraries/LibTextCodec/Encoder.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,16 @@ ErrorOr<ISO2022JPEncoder::State> ISO2022JPEncoder::process_item(u32 item, State
272272
}
273273

274274
// 10. Let pointer be the index pointer for code point in index jis0208.
275-
auto pointer = code_point_jis0208_index(item);
275+
//
276+
// AD-HOC: The jis0208 index contains 0xFFFD placeholder entries for unmapped pointers.
277+
// The generated inverse accessor code_point_jis0208_index() would match these
278+
// and return a bogus pointer for U+FFFD itself. We guard here rather than in
279+
// the Python generator to avoid changing inverse accessors for other indexes.
280+
Optional<u32> pointer;
281+
if (item == 0xFFFD)
282+
pointer = {};
283+
else
284+
pointer = code_point_jis0208_index(item);
276285

277286
// 11. If pointer is null, then:
278287
if (!pointer.has_value()) {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Harness status: OK
2+
3+
Found 12 tests
4+
5+
12 Pass
6+
Pass iso-2022-jp encoder: very basic
7+
Pass iso-2022-jp encoder: basics
8+
Pass iso-2022-jp encoder: Katakana
9+
Pass iso-2022-jp encoder: jis0208
10+
Pass iso-2022-jp encoder: SO/SI ESC
11+
Pass iso-2022-jp encoder: Roman SO/SI ESC
12+
Pass iso-2022-jp encoder: Katakana SO/SI ESC
13+
Pass iso-2022-jp encoder: jis0208 SO/SI ESC
14+
Pass iso-2022-jp encoder: U+FFFD
15+
Pass iso-2022-jp encoder: Roman U+FFFD
16+
Pass iso-2022-jp encoder: Katakana U+FFFD
17+
Pass iso-2022-jp encoder: jis0208 U+FFFD
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!doctype html>
2+
<meta charset=iso-2022-jp> <!-- if the server overrides this, it is stupid, as this is a testsuite -->
3+
<script src=../resources/testharness.js></script>
4+
<script src=../resources/testharnessreport.js></script>
5+
<div id=log></div>
6+
<script>
7+
function encode(input, output, desc) {
8+
test(function() {
9+
var a = document.createElement("a") // <a> uses document encoding for URL's query
10+
a.href = "https://example.com/?" + input
11+
assert_equals(a.search.substr(1), output) // remove leading "?"
12+
}, "iso-2022-jp encoder: " + desc)
13+
}
14+
15+
encode("s", "s", "very basic");
16+
encode("\u00A5\u203Es\\\uFF90\u4F69", "%1B(J\\~s%1B(B\\%1B$B%_PP%1B(B", "basics");
17+
encode("\uFF61", "%1B$B!%23%1B(B", "Katakana");
18+
encode("\u0393", "%1B$B&%23%1B(B", "jis0208");
19+
encode("\x0E\x0F\x1Bx", "%26%2365533%3B%26%2365533%3B%26%2365533%3Bx", "SO/SI ESC");
20+
encode("\u203E\x0E\x0F\x1Bx", "%1B(J~%26%2365533%3B%26%2365533%3B%26%2365533%3Bx%1B(B", "Roman SO/SI ESC");
21+
encode("\uFF61\x0E\x0F\x1Bx", "%1B$B!%23%1B(B%26%2365533%3B%26%2365533%3B%26%2365533%3Bx", "Katakana SO/SI ESC");
22+
encode("\u0393\x0E\x0F\x1Bx", "%1B$B&%23%1B(B%26%2365533%3B%26%2365533%3B%26%2365533%3Bx", "jis0208 SO/SI ESC");
23+
encode("\uFFFD", "%26%2365533%3B", "U+FFFD");
24+
encode("\u203E\uFFFD", "%1B(J~%26%2365533%3B%1B(B", "Roman U+FFFD");
25+
encode("\uFF61\uFFFD", "%1B$B!%23%1B(B%26%2365533%3B", "Katakana U+FFFD");
26+
encode("\u0393\uFFFD", "%1B$B&%23%1B(B%26%2365533%3B", "jis0208 U+FFFD");
27+
</script>

0 commit comments

Comments
 (0)