17
17
// This makes for some ugly code, but it is faster. Hopefully in the future
18
18
// with MIR support the compiler will get smarter about this.
19
19
20
- use std:: { ptr , mem , str, slice, char } ;
20
+ use std:: { str, slice, char } ;
21
21
use object:: Object ;
22
22
use number:: Number ;
23
23
use { JsonValue , Error , Result } ;
@@ -27,6 +27,10 @@ use { JsonValue, Error, Result };
27
27
const MAX_PRECISION : u64 = 576460752303423500 ;
28
28
29
29
30
+ // How many nested Objects/Arrays are allowed to be parsed
31
+ const DEPTH_LIMIT : usize = 512 ;
32
+
33
+
30
34
// Position is only used when we stumble upon an unexpected character. We don't
31
35
// track lines during parsing, as that would mean doing unnecessary work.
32
36
// Instead, if an error occurs, we figure out the line and column from the
@@ -121,6 +125,20 @@ macro_rules! expect_byte_ignore_whitespace {
121
125
} )
122
126
}
123
127
128
+ // Expect to find EOF or just whitespaces leading to EOF after a JSON value
129
+ macro_rules! expect_eof {
130
+ ( $parser: ident) => ( {
131
+ while !$parser. is_eof( ) {
132
+ match $parser. read_byte( ) {
133
+ 9 ... 13 | 32 => $parser. bump( ) ,
134
+ ch => {
135
+ $parser. bump( ) ;
136
+ return $parser. unexpected_character( ch) ;
137
+ }
138
+ }
139
+ }
140
+ } )
141
+ }
124
142
125
143
// Expect a particular byte to be next. Also available with a variant
126
144
// creates a `match` expression just to ease some pain.
@@ -350,52 +368,6 @@ macro_rules! expect_fraction {
350
368
} )
351
369
}
352
370
353
-
354
- // This is where the magic happens. This macro will read from the source
355
- // and try to create an instance of `JsonValue`. Note that it only reads
356
- // bytes that _begin_ a JSON value, however it can also accept an optional
357
- // pattern with custom logic. This is used in arrays, which expect either
358
- // a value or a closing bracket `b"]"`.
359
- macro_rules! expect_value {
360
- { $parser: ident $( , $byte: pat => $then: expr ) * } => ( {
361
- let ch = expect_byte_ignore_whitespace!( $parser) ;
362
-
363
- match ch {
364
- $(
365
- $byte => $then,
366
- ) *
367
- b'[' => JsonValue :: Array ( try!( $parser. read_array( ) ) ) ,
368
- b'{' => JsonValue :: Object ( try!( $parser. read_object( ) ) ) ,
369
- b'"' => expect_string!( $parser) . into( ) ,
370
- b'0' => JsonValue :: Number ( allow_number_extensions!( $parser) ) ,
371
- b'1' ... b'9' => {
372
- JsonValue :: Number ( expect_number!( $parser, ch) )
373
- } ,
374
- b'-' => {
375
- let ch = expect_byte!( $parser) ;
376
- JsonValue :: Number ( - match ch {
377
- b'0' => allow_number_extensions!( $parser) ,
378
- b'1' ... b'9' => expect_number!( $parser, ch) ,
379
- _ => return $parser. unexpected_character( ch)
380
- } )
381
- }
382
- b't' => {
383
- expect_sequence!( $parser, b'r' , b'u' , b'e' ) ;
384
- JsonValue :: Boolean ( true )
385
- } ,
386
- b'f' => {
387
- expect_sequence!( $parser, b'a' , b'l' , b's' , b'e' ) ;
388
- JsonValue :: Boolean ( false )
389
- } ,
390
- b'n' => {
391
- expect_sequence!( $parser, b'u' , b'l' , b'l' ) ;
392
- JsonValue :: Null
393
- } ,
394
- _ => return $parser. unexpected_character( ch)
395
- }
396
- } )
397
- }
398
-
399
371
impl < ' a > Parser < ' a > {
400
372
pub fn new ( source : & ' a str ) -> Self {
401
373
Parser {
@@ -704,102 +676,146 @@ impl<'a> Parser<'a> {
704
676
Ok ( Number :: from_parts ( true , num, ( big_e. saturating_add ( e * sign) ) ) )
705
677
}
706
678
707
- // Given how compilcated reading numbers and strings is, reading objects
708
- // is actually pretty simple.
709
- fn read_object ( & mut self ) -> Result < Object > {
710
- let key = expect ! { self ,
711
- b'}' => return Ok ( Object :: new( ) ) ,
712
- b'\"' => expect_string!( self )
713
- } ;
679
+ // Parse away!
680
+ fn parse ( & mut self ) -> Result < JsonValue > {
681
+ let mut stack = Vec :: with_capacity ( 3 ) ;
682
+ let mut ch = expect_byte_ignore_whitespace ! ( self ) ;
714
683
715
- let mut object = Object :: with_capacity ( 3 ) ;
684
+ ' parsing: loop {
685
+ let mut value = match ch {
686
+ b'[' => {
687
+ ch = expect_byte_ignore_whitespace ! ( self ) ;
716
688
717
- expect ! ( self , b':' ) ;
689
+ if ch != b']' {
690
+ if stack. len ( ) == DEPTH_LIMIT {
691
+ return Err ( Error :: ExceededDepthLimit ) ;
692
+ }
718
693
719
- object. insert ( key, expect_value ! ( self ) ) ;
694
+ stack. push ( StackBlock :: Array ( Vec :: with_capacity ( 2 ) ) ) ;
695
+ continue ' parsing;
696
+ }
720
697
721
- loop {
722
- let key = expect ! { self ,
723
- b'}' => break ,
724
- b',' => {
725
- expect!( self , b'"' ) ;
726
- expect_string!( self )
698
+ JsonValue :: Array ( Vec :: new ( ) )
699
+ } ,
700
+ b'{' => {
701
+ ch = expect_byte_ignore_whitespace ! ( self ) ;
702
+
703
+ if ch != b'}' {
704
+ if stack. len ( ) == DEPTH_LIMIT {
705
+ return Err ( Error :: ExceededDepthLimit ) ;
706
+ }
707
+
708
+ let mut object = Object :: with_capacity ( 3 ) ;
709
+
710
+ if ch != b'"' {
711
+ return self . unexpected_character ( ch)
712
+ }
713
+
714
+ object. insert ( expect_string ! ( self ) , JsonValue :: Null ) ;
715
+ expect ! ( self , b':' ) ;
716
+
717
+ stack. push ( StackBlock :: Object ( object) ) ;
718
+
719
+ ch = expect_byte_ignore_whitespace ! ( self ) ;
720
+
721
+ continue ' parsing;
722
+ }
723
+
724
+ JsonValue :: Object ( Object :: new ( ) )
725
+ } ,
726
+ b'"' => expect_string ! ( self ) . into ( ) ,
727
+ b'0' => JsonValue :: Number ( allow_number_extensions ! ( self ) ) ,
728
+ b'1' ... b'9' => {
729
+ JsonValue :: Number ( expect_number ! ( self , ch) )
730
+ } ,
731
+ b'-' => {
732
+ let ch = expect_byte ! ( self ) ;
733
+ JsonValue :: Number ( - match ch {
734
+ b'0' => allow_number_extensions ! ( self ) ,
735
+ b'1' ... b'9' => expect_number ! ( self , ch) ,
736
+ _ => return self . unexpected_character ( ch)
737
+ } )
727
738
}
739
+ b't' => {
740
+ expect_sequence ! ( self , b'r' , b'u' , b'e' ) ;
741
+ JsonValue :: Boolean ( true )
742
+ } ,
743
+ b'f' => {
744
+ expect_sequence ! ( self , b'a' , b'l' , b's' , b'e' ) ;
745
+ JsonValue :: Boolean ( false )
746
+ } ,
747
+ b'n' => {
748
+ expect_sequence ! ( self , b'u' , b'l' , b'l' ) ;
749
+ JsonValue :: Null
750
+ } ,
751
+ _ => return self . unexpected_character ( ch)
728
752
} ;
729
753
730
- expect ! ( self , b':' ) ;
754
+ ' popping: loop {
755
+ match stack. pop ( ) {
756
+ None => {
757
+ expect_eof ! ( self ) ;
731
758
732
- object . insert ( key , expect_value ! ( self ) ) ;
733
- }
759
+ return Ok ( value ) ;
760
+ } ,
734
761
735
- Ok ( object )
736
- }
762
+ Some ( StackBlock :: Array ( mut array ) ) => {
763
+ array . push ( value ) ;
737
764
738
- // And reading arrays is simpler still!
739
- fn read_array ( & mut self ) -> Result < Vec < JsonValue > > {
740
- let first = expect_value ! { self , b']' => return Ok ( Vec :: new( ) ) } ;
765
+ ch = expect_byte_ignore_whitespace ! ( self ) ;
741
766
742
- let mut array = Vec :: with_capacity ( 2 ) ;
767
+ match ch {
768
+ b',' => {
769
+ stack. push ( StackBlock :: Array ( array) ) ;
743
770
744
- unsafe {
745
- // First member can be written to the array without any checks!
746
- ptr:: copy_nonoverlapping (
747
- & first as * const JsonValue ,
748
- array. as_mut_ptr ( ) ,
749
- 1
750
- ) ;
751
- mem:: forget ( first) ;
752
- array. set_len ( 1 ) ;
753
- }
771
+ ch = expect_byte_ignore_whitespace ! ( self ) ;
754
772
755
- expect ! {
756
- self ,
757
- b']' => return Ok ( array) ,
758
- b',' => {
759
- // Same for the second one!
760
- let value = expect_value!( self ) ;
761
- unsafe {
762
- ptr:: copy_nonoverlapping(
763
- & value as * const JsonValue ,
764
- array. as_mut_ptr( ) . offset( 1 ) ,
765
- 1
766
- ) ;
767
- mem:: forget( value) ;
768
- array. set_len( 2 ) ;
769
- }
770
- }
771
- }
773
+ continue ' parsing;
774
+ } ,
775
+ b']' => {
776
+ value = JsonValue :: Array ( array) ;
777
+ continue ' popping;
778
+ } ,
779
+ _ => return self . unexpected_character ( ch)
780
+ }
781
+ } ,
772
782
773
- loop {
774
- expect ! { self ,
775
- b']' => break ,
776
- b',' => array. push( expect_value!( self ) )
777
- } ;
778
- }
783
+ Some ( StackBlock :: Object ( mut object) ) => {
784
+ object. override_last ( value) ;
779
785
780
- Ok ( array)
781
- }
786
+ ch = expect_byte_ignore_whitespace ! ( self ) ;
782
787
783
- // Parse away!
784
- fn parse ( & mut self ) -> Result < JsonValue > {
785
- let value = expect_value ! ( self ) ;
788
+ match ch {
789
+ b',' => {
790
+ expect ! ( self , b'"' ) ;
791
+ object. insert ( expect_string ! ( self ) , JsonValue :: Null ) ;
792
+ expect ! ( self , b':' ) ;
786
793
787
- // We have read whatever value was there, but we need to make sure
788
- // there is nothing left to read - if there is, that's an error.
789
- while !self . is_eof ( ) {
790
- match self . read_byte ( ) {
791
- 9 ... 13 | 32 => self . bump ( ) ,
792
- ch => {
793
- self . bump ( ) ;
794
- return self . unexpected_character ( ch) ;
794
+ stack. push ( StackBlock :: Object ( object) ) ;
795
+
796
+ ch = expect_byte_ignore_whitespace ! ( self ) ;
797
+
798
+ continue ' parsing;
799
+ } ,
800
+ b'}' => {
801
+ value = JsonValue :: Object ( object) ;
802
+
803
+ continue ' popping;
804
+ } ,
805
+ _ => return self . unexpected_character ( ch)
806
+ }
807
+ } ,
795
808
}
796
809
}
797
810
}
798
-
799
- Ok ( value)
800
811
}
801
812
}
802
813
814
+ enum StackBlock {
815
+ Array ( Vec < JsonValue > ) ,
816
+ Object ( Object ) ,
817
+ }
818
+
803
819
// All that hard work, and in the end it's just a single function in the API.
804
820
#[ inline]
805
821
pub fn parse ( source : & str ) -> Result < JsonValue > {
0 commit comments