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]); diff --git a/core/tests/suites/json.ts b/core/tests/suites/json.ts index 3068767..7b2b107 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, @@ -72,7 +72,11 @@ const tests = group('json', [ .dictionary(genString(), fc.boolean()) .map((v) => new Map(Object.entries(v))) )), - test('json', () => roundtripTest(s.json, genJson())), + group('json', [ + test('plain', () => roundtripTest(s.json, genJson())), + test('with "__proto__" key', () => + roundtrip(s.json, [{ ['__proto__']: [] }])), + ]), group('recursive', [ test('base case', () => { type List = @@ -553,10 +557,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, + } ); }