11import { JSON } from "../.." ;
2- import { deserializeBoolean } from "./bool" ;
2+ import { deserializeBooleanCode } from "./bool" ;
33import { deserializeFloat } from "./float" ;
44import { deserializeObject , deserializeJsonArray , getParseSrc } from "./object" ;
55import { deserializeString } from "./string" ;
66import { BRACE_LEFT , BRACKET_LEFT , CHAR_N , QUOTE } from "../../custom/chars" ;
77
8+ const NULL_WORD : u64 = 30399761348886638 ;
9+
810export function deserializeArbitrary (
911 srcStart : usize ,
1012 srcEnd : usize ,
1113 dst : usize ,
1214) : JSON . Value {
1315 const v = parseArbitraryValue ( srcStart , srcEnd ) ;
16+ if ( changetype < usize > ( v ) == 0 ) return v ;
1417 // Reuse path (`JSON.parse<JSON.Value>(data, out)`): write the parsed bits into
1518 // the caller's handle (with the GC barrier for any managed payload).
1619 return dst != 0 ? JSON . Value . __adoptInto ( dst , v ) : v ;
1720}
1821
1922function parseArbitraryValue ( srcStart : usize , srcEnd : usize ) : JSON . Value {
23+ if ( srcStart >= srcEnd ) return changetype < JSON . Value > ( 0 ) ;
2024 const firstChar = load < u16 > ( srcStart ) ;
2125 if (
2226 firstChar == QUOTE ||
@@ -29,19 +33,36 @@ function parseArbitraryValue(srcStart: usize, srcEnd: usize): JSON.Value {
2933 const src = getParseSrc ( ) ;
3034 if ( src . length != 0 ) {
3135 const end = JSON . Util . scanValueEnd < JSON . Value > ( srcStart , srcEnd ) ;
36+ // A zero end is the scanner's failure sentinel. Never retain it in a
37+ // lazy slice: subtracting the source base from zero would underflow and
38+ // later materialization could read outside the source value.
39+ if ( end == 0 ) return changetype < JSON . Value > ( 0 ) ;
3240 return JSON . Value . fromSlice ( srcStart , end , src ) ;
3341 }
34- if ( firstChar == QUOTE )
35- return JSON . Value . from ( deserializeString ( srcStart , srcEnd ) ) ;
36- return firstChar == BRACE_LEFT
37- ? JSON . Value . from ( deserializeObject ( srcStart , srcEnd , 0 ) )
38- : JSON . Value . from ( deserializeJsonArray ( srcStart , srcEnd , 0 ) ) ;
42+ if ( firstChar == QUOTE ) {
43+ const value = deserializeString ( srcStart , srcEnd ) ;
44+ return changetype < usize > ( value ) != 0
45+ ? JSON . Value . from ( value )
46+ : changetype < JSON . Value > ( 0 ) ;
47+ }
48+ const composite =
49+ firstChar == BRACE_LEFT
50+ ? changetype < usize > ( deserializeObject ( srcStart , srcEnd , 0 ) )
51+ : changetype < usize > ( deserializeJsonArray ( srcStart , srcEnd , 0 ) ) ;
52+ return composite != 0
53+ ? firstChar == BRACE_LEFT
54+ ? JSON . Value . from ( changetype < JSON . Obj > ( composite ) )
55+ : JSON . Value . from ( changetype < JSON . Arr > ( composite ) )
56+ : changetype < JSON . Value > ( 0 ) ;
3957 } else if ( firstChar - 48 <= 9 || firstChar == 45 ) {
4058 return JSON . Value . from ( deserializeFloat < f64 > ( srcStart , srcEnd ) ) ;
4159 } else if ( firstChar == 116 || firstChar == 102 ) {
42- return JSON . Value . from ( deserializeBoolean ( srcStart , srcEnd ) ) ;
60+ const code = deserializeBooleanCode ( srcStart , srcEnd ) ;
61+ return code != 0 ? JSON . Value . from ( code == 2 ) : changetype < JSON . Value > ( 0 ) ;
4362 } else if ( firstChar == CHAR_N ) {
63+ if ( srcEnd - srcStart < 8 || load < u64 > ( srcStart ) != NULL_WORD )
64+ return changetype < JSON . Value > ( 0 ) ;
4465 return JSON . Value . from < usize > ( 0 ) ;
4566 }
46- return unreachable ( ) ;
67+ return changetype < JSON . Value > ( 0 ) ;
4768}
0 commit comments