From c1ecf691e827c994a9f57f4cb0249a64853d3d7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dejan=20Leki=C4=87?= Date: Wed, 14 Jan 2026 00:37:57 +0000 Subject: [PATCH 1/3] This should fix the issue in Parser.scan() --- source/dcell/parser.d | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source/dcell/parser.d b/source/dcell/parser.d index 0fc6a2d..7f1cf2d 100644 --- a/source/dcell/parser.d +++ b/source/dcell/parser.d @@ -400,9 +400,15 @@ private: { parseState = ParseState.ini; size_t index = 0; - dchar dch = decode(cast(string) accum, index); +q try + { + dchar dch = decode(cast(const(char)[]) accum, index); + postKey(Key.graph, dch, Modifiers.none); + } + catch (UTFException) + { + } accum = null; - postKey(Key.graph, dch, Modifiers.none); } break; case ParseState.ini: @@ -1283,6 +1289,10 @@ private: assert(ev[0].key.key == Key.graph); assert(ev[0].key.ch == '€'); + // invalid unicode - should not crash + assert(p.parse("\xE2 ")); + assert(p.events().length == 0); + // SOS (no event) assert(p.parse(['\x1b', 'X', 'p', '\x1b', '\\'])); assert(p.events().length == 0); From fa4543ea7ea920bf23f2304492a0c8469647738c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dejan=20Leki=C4=87?= Date: Wed, 14 Jan 2026 00:41:43 +0000 Subject: [PATCH 2/3] Somehow an extra `q` sneaked in. --- source/dcell/parser.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/dcell/parser.d b/source/dcell/parser.d index 7f1cf2d..b0e57c5 100644 --- a/source/dcell/parser.d +++ b/source/dcell/parser.d @@ -400,7 +400,7 @@ private: { parseState = ParseState.ini; size_t index = 0; -q try + try { dchar dch = decode(cast(const(char)[]) accum, index); postKey(Key.graph, dch, Modifiers.none); From ee7c51c0246fb480279c6959823c6b9be86d0ee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dejan=20Leki=C4=87?= Date: Wed, 14 Jan 2026 01:00:35 +0000 Subject: [PATCH 3/3] I have updated the unit tests in source/dcell/parser.d to more rigorously verify the UTF-8 error handling logic. --- source/dcell/parser.d | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/source/dcell/parser.d b/source/dcell/parser.d index b0e57c5..4ad23d8 100644 --- a/source/dcell/parser.d +++ b/source/dcell/parser.d @@ -1289,9 +1289,18 @@ private: assert(ev[0].key.key == Key.graph); assert(ev[0].key.ch == '€'); - // invalid unicode - should not crash - assert(p.parse("\xE2 ")); - assert(p.events().length == 0); + // invalid unicode - should not crash, and should preserve subsequent valid input + assert(p.parse("\xE2 A")); + ev = p.events(); + assert(ev.length == 1); + assert(ev[0].key.ch == 'A'); + + // valid multi-byte followed by valid input + assert(p.parse("\xE2\x82\xacB")); + ev = p.events(); + assert(ev.length == 2); + assert(ev[0].key.ch == '€'); + assert(ev[1].key.ch == 'B'); // SOS (no event) assert(p.parse(['\x1b', 'X', 'p', '\x1b', '\\']));