From ead77813dac281bc41e54f2d88411a8bbb08445a Mon Sep 17 00:00:00 2001 From: Thor Whalen <1906276+thorwhalen@users.noreply.github.com> Date: Fri, 10 Jul 2026 13:02:32 +0200 Subject: [PATCH] fix(core): remove NUL-byte separator from the when-clause regex tokenizer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The regex-literal token packed `pattern + + flags` into one string and split on that same NUL downstream. Self-consistent (tests passed), but it made when.ts and the built dist binary to git (no diff/blame rendering) and was fragile — a naive NUL->space "cleanup" would break any regex pattern containing a space (e.g. /foo bar/). Store `pattern` and `flags` as distinct Token fields (no separator at all). Behavior-identical for every input; adds a regression test for a space-containing pattern, previously only guarded by the invisible NUL and never tested. Discovered during the v1.14-v1.18 pre-wiring review (#51). No public API or runtime-behavior change. Claude-Session: https://claude.ai/code/session_01A1PykLHv2BjQRQhspjvPWy --- .../core-regex-token-no-nul-separator.md | Bin 0 -> 751 bytes packages/core/src/when.test.ts | 9 +++++++++ packages/core/src/when.ts | Bin 14281 -> 14535 bytes 3 files changed, 9 insertions(+) create mode 100644 .changeset/core-regex-token-no-nul-separator.md diff --git a/.changeset/core-regex-token-no-nul-separator.md b/.changeset/core-regex-token-no-nul-separator.md new file mode 100644 index 0000000000000000000000000000000000000000..d679833540397b0e94b13c158c425cc246855b77 GIT binary patch literal 751 zcmYk4F^=0X5Jgk-6azQ570cUiw`G7}5d=xEkvNhDrbvOLtaYj!A}7pA@+q&A6e0u; zIsg4Xtn1qBxXVkF-80RcyV2CxGhby2SD`!#y?*~(x3?^mWah{@MCxOhw%R(1uRF&} z5{fd&8|82juRkQ7>E*swzLuyEU4#bqy4-TR^ z;)mEB|P9LeNTJ;=nV5C8FRnfr*)cXFZbvzY&-b!IP78qJNAqF1Q$uqH;7})qE(yrGx z9NTRHslRH{wix-F-rXKj5L(0HEUY@xrg~k2%bvwEeJ~6%|r9lhd?dI zr{;L3Zy3~n10Ww(>NrM~WFA2`8+h{`Gx)2jcvs(L>Q$Ug@2>x$B4>8)c%pUGZX`{n zm65L+Vyza;+OeY^FG8+@?9|Ulyu`!SCJYfsQBu+}G)a)bQN|$Qy$tGM>f!S+M?v!? zA&cO#%rRu?GG0rI$=n~~iF{Gp8j3xh&1;}}X`OcT^5qjjAub@Bq<*kcH?kk(Z2kb- CNeHX} literal 0 HcmV?d00001 diff --git a/packages/core/src/when.test.ts b/packages/core/src/when.test.ts index aa30dc9..5fd0feb 100644 --- a/packages/core/src/when.test.ts +++ b/packages/core/src/when.test.ts @@ -64,6 +64,15 @@ describe('when-clause DSL — parsing', () => { expect(compileWhen('path =~ "\\.ts$"').evaluate({ path: 'foo.md' })).toBe(false); }); + it('parses a regex literal whose pattern contains a space', () => { + // A space in the pattern must not be treated as a token/flag separator + // (the regex token now carries pattern and flags as distinct fields). + expect(compileWhen('label =~ /foo bar/').evaluate({ label: 'a foo bar b' })).toBe(true); + expect(compileWhen('label =~ /foo bar/').evaluate({ label: 'foobar' })).toBe(false); + // ...with flags still applied. + expect(compileWhen('label =~ /foo bar/i').evaluate({ label: 'FOO BAR' })).toBe(true); + }); + it('parses in / not in', () => { expect(compileWhen('lang in langs').evaluate({ lang: 'ts', langs: ['ts', 'js'] })).toBe(true); expect(compileWhen('lang in langs').evaluate({ lang: 'py', langs: ['ts', 'js'] })).toBe(false); diff --git a/packages/core/src/when.ts b/packages/core/src/when.ts index cf5b3212a4ef5d69f2be2de183af063f3786baec..17b759f9dd8f0f2036611cf11a2811ad623ed274 100644 GIT binary patch delta 367 zcmYL_!AiqG5Qg#4iwH^{K>tHS+t8+X6*2e%3f@EtnI_Y?bh{gOH^rR#5Iy@2LLNed zK9rj@*yF%I-+c4`>YtBqG1$$c2rpdl=gjFfD`+L_JGghoN>X7lPTvZ#u~of@(#aGV zm98?J!*WT69LpM3xA}7b5m1tIY!sx}vIR-47(yZ4lB_rdsT_(qw|IJP8M_vuO^ips znXNhRF=@}a_nC*zB!zWGr~<-bWvCF6F{b}}nO2U3Y6B;kUQ!!ugq_(^3TG#s!%CaX ze?bwHRBL(@{vvNlY(} zRj^ek(JM>LDNWTYF38C&(E#euR7fmVh%PQE%FIjGQGn2~lMPiRCUdLtvqN=Gj#ic1 J9IjR%1OV2@CAR