@@ -7,9 +7,11 @@ pub use escape::check_escape;
77pub ( crate ) mod allowed_chars {
88 pub ( crate ) fn comment ( s : & str ) -> Result < ( ) , Vec < usize > > {
99 let mut err_indices = Vec :: new ( ) ;
10+ let bytes = s. as_bytes ( ) ;
1011
11- for ( i, c) in s. chars ( ) . enumerate ( ) {
12- if c != '\t' && c. is_control ( ) {
12+ for ( i, & b) in bytes. iter ( ) . enumerate ( ) {
13+ // Tab is 0x09, control chars are 0x00-0x1F and 0x7F (all ASCII)
14+ if b != b'\t' && ( b < 0x20 || b == 0x7F ) {
1315 err_indices. push ( i) ;
1416 }
1517 }
@@ -19,12 +21,13 @@ pub(crate) mod allowed_chars {
1921
2022 pub ( crate ) fn string ( s : & str ) -> Result < ( ) , Vec < usize > > {
2123 let mut err_indices = Vec :: new ( ) ;
24+ let bytes = s. as_bytes ( ) ;
2225
23- for ( i, c ) in s . chars ( ) . enumerate ( ) {
24- if c != '\t'
25- && ( ( '\u{0000}' ..= '\u{0008}' ) . contains ( & c )
26- || ( '\u{000A}' ..= '\u{001F}' ) . contains ( & c )
27- || c == '\u{007F}' )
26+ for ( i, & b ) in bytes . iter ( ) . enumerate ( ) {
27+ // Check for disallowed control chars: 0x00-0x08, 0x0A-0x1F, 0x7F
28+ // Tab (0x09) is allowed
29+ if b != b'\t'
30+ && ( ( 0x00 ..= 0x08 ) . contains ( & b ) || ( 0x0A ..= 0x1F ) . contains ( & b ) || b == 0x7F )
2831 {
2932 err_indices. push ( i) ;
3033 }
@@ -35,14 +38,14 @@ pub(crate) mod allowed_chars {
3538
3639 pub ( crate ) fn multi_line_string ( s : & str ) -> Result < ( ) , Vec < usize > > {
3740 let mut err_indices = Vec :: new ( ) ;
38-
39- for ( i , c ) in s . chars ( ) . enumerate ( ) {
40- if c != '\t'
41- && c != '\n'
42- && c != '\r '
43- && ( ( '\u{0000}' ..= '\u{0008}' ) . contains ( & c )
44- || ( '\u{000A}' ..= '\u{001F}' ) . contains ( & c )
45- || c == '\u{007F}' )
41+ let bytes = s . as_bytes ( ) ;
42+
43+ for ( i , & b ) in bytes . iter ( ) . enumerate ( ) {
44+ // Tab (0x09), LF (0x0A), CR (0x0D) are allowed
45+ if b != b'\t '
46+ && b != b'\n'
47+ && b != b'\r'
48+ && ( ( 0x00 ..= 0x08 ) . contains ( & b ) || ( 0x0A ..= 0x1F ) . contains ( & b ) || b == 0x7F )
4649 {
4750 err_indices. push ( i) ;
4851 }
@@ -53,9 +56,11 @@ pub(crate) mod allowed_chars {
5356
5457 pub ( crate ) fn string_literal ( s : & str ) -> Result < ( ) , Vec < usize > > {
5558 let mut err_indices = Vec :: new ( ) ;
59+ let bytes = s. as_bytes ( ) ;
5660
57- for ( i, c) in s. chars ( ) . enumerate ( ) {
58- if c != '\t' && c. is_control ( ) {
61+ for ( i, & b) in bytes. iter ( ) . enumerate ( ) {
62+ // Tab is 0x09, control chars are 0x00-0x1F and 0x7F
63+ if b != b'\t' && ( b < 0x20 || b == 0x7F ) {
5964 err_indices. push ( i) ;
6065 }
6166 }
@@ -65,9 +70,11 @@ pub(crate) mod allowed_chars {
6570
6671 pub ( crate ) fn multi_line_string_literal ( s : & str ) -> Result < ( ) , Vec < usize > > {
6772 let mut err_indices = Vec :: new ( ) ;
73+ let bytes = s. as_bytes ( ) ;
6874
69- for ( i, c) in s. chars ( ) . enumerate ( ) {
70- if c != '\t' && c != '\n' && c != '\r' && c. is_control ( ) {
75+ for ( i, & b) in bytes. iter ( ) . enumerate ( ) {
76+ // Tab (0x09), LF (0x0A), CR (0x0D) are allowed
77+ if b != b'\t' && b != b'\n' && b != b'\r' && ( b < 0x20 || b == 0x7F ) {
7178 err_indices. push ( i) ;
7279 }
7380 }
0 commit comments