From 1f9af6ee3e92885818db18a0f44d0c5628aec8ab Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Wed, 12 Aug 2026 17:39:09 +0900 Subject: [PATCH] fix: reject unsupported SKK expressions --- map/README | 6 +++--- map/skk2ktrans | 2 ++ tests/data/skk/source.skk.utf8 | 2 +- tests/skk2ktrans_test.py | 7 +++++++ 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/map/README b/map/README index 073cb20..a225d10 100644 --- a/map/README +++ b/map/README @@ -32,9 +32,9 @@ the normal build image. `skk2ktrans` accepts one or more EUC-JP SKK files (or standard input), writes UTF-8 tab-separated rows, and merges input in command-line and source order. -It strips annotations, deduplicates candidates, and omits expressions and -candidates containing whitespace. Escaped candidate delimiters are rejected; -rewrite or omit those entries before import. +It strips annotations, deduplicates candidates, and omits candidates containing +whitespace. Rows containing expressions or escaped candidate delimiters are +rejected; rewrite or omit those rows before import. `verifymap.py` checks UTF-8, row structure, unique keys, 64-rune keys and values, canonical candidate spacing, and duplicate dictionary candidates. diff --git a/map/skk2ktrans b/map/skk2ktrans index a8e077a..4908d65 100755 --- a/map/skk2ktrans +++ b/map/skk2ktrans @@ -34,6 +34,8 @@ function add(k, v, id) { fail("invalid row") if(field ~ /\\/) fail("escaped candidates are unsupported") + if(field ~ /\/[([#]/) + fail("expression candidates are unsupported") n = split(substr(field, 2, length(field)-2), value, "/") for(i = 1; i <= n; i++) add(key, value[i]) diff --git a/tests/data/skk/source.skk.utf8 b/tests/data/skk/source.skk.utf8 index 08ddf47..217ae4e 100644 --- a/tests/data/skk/source.skk.utf8 +++ b/tests/data/skk/source.skk.utf8 @@ -3,4 +3,4 @@ えがお /笑顔;face/ かんじ /感じ/漢字;duplicate/ きごう /記号;symbol/普通/ -むこう /候補 with space/(concat "式" "候補")/[無効]/#0/ +むこう /候補 with space/ diff --git a/tests/skk2ktrans_test.py b/tests/skk2ktrans_test.py index dc2463c..90abc72 100755 --- a/tests/skk2ktrans_test.py +++ b/tests/skk2ktrans_test.py @@ -36,6 +36,13 @@ class Skk2KtransTest(unittest.TestCase): self.assertNotEqual(result.returncode, 0) self.assertIn(b"escaped candidates are unsupported", result.stderr) + def test_expression_candidate_is_rejected(self): + source = b'key /(concat "a/b")/literal/\n' + result = subprocess.run( + [CONVERTER], input=source, capture_output=True, check=False) + self.assertNotEqual(result.returncode, 0) + self.assertIn(b"expression candidates are unsupported", result.stderr) + if __name__ == "__main__": unittest.main()