From 45409e32a35c16ffd1f8051153692dbccc501c12 Mon Sep 17 00:00:00 2001 From: Ethan Brown Date: Tue, 3 Feb 2026 19:24:20 -0800 Subject: [PATCH 1/3] TODO: fix error in json / schema / json While testing #39, I stumbled on an error in the json / schema / json test. I was able to reproduce it with the `fast-check` seed and path. I can tackle fixing this, but I'm going to focus on other things for now. --- core/tests/suites/json.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/core/tests/suites/json.ts b/core/tests/suites/json.ts index 3068767..2d680d5 100644 --- a/core/tests/suites/json.ts +++ b/core/tests/suites/json.ts @@ -59,7 +59,7 @@ const tests = group('json', [ )), test('pair', () => roundtrip(s.pair(s.string, s.number), ['wat', 2] as [string, number])), - test('tripple', () => + test('triple', () => roundtrip(s.triple(s.string, s.number, s.boolean), ['wat', 2, false] as [ string, number, @@ -73,6 +73,12 @@ const tests = group('json', [ .map((v) => new Map(Object.entries(v))) )), test('json', () => roundtripTest(s.json, genJson())), + test('json - FIXME', () => + roundtripTest(s.json, genJson(), { + seed: -427826544, + path: '95:1:85:85', + endOnFailure: true, + })), group('recursive', [ test('base case', () => { type List = @@ -553,10 +559,17 @@ function genJson(lvl = 0): fc.Arbitrary { ); } -function roundtripTest(schema: Schema, gen: fc.Arbitrary): void { +function roundtripTest( + schema: Schema, + gen: fc.Arbitrary, + assertOptions?: fc.Parameters<[v: T]> +): void { fc.assert( fc.property(gen, (v) => roundtrip(schema, v)), - { includeErrorInReport: true } + { + includeErrorInReport: true, + ...assertOptions, + } ); } From 177906a2536ef32016a778b47da1b0c1a3dc83c2 Mon Sep 17 00:00:00 2001 From: Marcelo Lazaroni Date: Fri, 6 Feb 2026 16:09:47 +0000 Subject: [PATCH 2/3] Use explicit __proto__ test --- core/tests/suites/json.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/core/tests/suites/json.ts b/core/tests/suites/json.ts index 2d680d5..7b2b107 100644 --- a/core/tests/suites/json.ts +++ b/core/tests/suites/json.ts @@ -72,13 +72,11 @@ const tests = group('json', [ .dictionary(genString(), fc.boolean()) .map((v) => new Map(Object.entries(v))) )), - test('json', () => roundtripTest(s.json, genJson())), - test('json - FIXME', () => - roundtripTest(s.json, genJson(), { - seed: -427826544, - path: '95:1:85:85', - endOnFailure: true, - })), + group('json', [ + test('plain', () => roundtripTest(s.json, genJson())), + test('with "__proto__" key', () => + roundtrip(s.json, [{ ['__proto__']: [] }])), + ]), group('recursive', [ test('base case', () => { type List = From d70c1a1afec0ed0d8d642601788f105c16b022bd Mon Sep 17 00:00:00 2001 From: Marcelo Lazaroni Date: Fri, 6 Feb 2026 16:10:04 +0000 Subject: [PATCH 3/3] Fix decoding of objects with protected keys --- core/src/json/decoder.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/json/decoder.ts b/core/src/json/decoder.ts index 0628bae..38d84b5 100644 --- a/core/src/json/decoder.ts +++ b/core/src/json/decoder.ts @@ -210,7 +210,8 @@ const objectMap = (decoder: Decoder): Decoder> => return failure('expected object but found ' + typeof input); } - const result = {} as ObjectMap; + // object without a prototype or built-in functions. + const result = Object.create(null) as ObjectMap; for (const field in input) { // @ts-ignore const decoded = decoder.run(input[field]);