@@ -871,10 +871,7 @@ fn container_to_string(value: &[u8], offset: &mut usize, json: &mut String) {
871871 let jentry_encoded = read_u32 ( value, jentry_offset) . unwrap ( ) ;
872872 let jentry = JEntry :: decode_jentry ( jentry_encoded) ;
873873 let key_length = jentry. length as usize ;
874- let key = unsafe {
875- std:: str:: from_utf8_unchecked ( & value[ key_offset..key_offset + key_length] )
876- } ;
877- keys. push_back ( key) ;
874+ keys. push_back ( ( key_offset, key_offset + key_length) ) ;
878875 jentry_offset += 4 ;
879876 key_offset += key_length;
880877 }
@@ -883,8 +880,8 @@ fn container_to_string(value: &[u8], offset: &mut usize, json: &mut String) {
883880 if i > 0 {
884881 json. push ( ',' ) ;
885882 }
886- let key = keys. pop_front ( ) . unwrap ( ) ;
887- json . extend ( format ! ( "{:?}" , key ) . chars ( ) ) ;
883+ let ( key_start , key_end ) = keys. pop_front ( ) . unwrap ( ) ;
884+ escape_scalar_string ( value , key_start , key_end , json ) ;
888885 json. push ( ':' ) ;
889886 scalar_to_string ( value, & mut jentry_offset, & mut value_offset, json) ;
890887 }
@@ -912,10 +909,7 @@ fn scalar_to_string(
912909 json. push_str ( & format ! ( "{num}" ) ) ;
913910 }
914911 STRING_TAG => {
915- let val = unsafe {
916- std:: str:: from_utf8_unchecked ( & value[ * value_offset..* value_offset + length] )
917- } ;
918- json. extend ( format ! ( "{:?}" , val) . chars ( ) ) ;
912+ escape_scalar_string ( value, * value_offset, * value_offset + length, json) ;
919913 }
920914 CONTAINER_TAG => {
921915 container_to_string ( value, value_offset, json) ;
@@ -926,6 +920,38 @@ fn scalar_to_string(
926920 * value_offset += length;
927921}
928922
923+ fn escape_scalar_string ( value : & [ u8 ] , start : usize , end : usize , json : & mut String ) {
924+ json. push ( '\"' ) ;
925+ let mut last_start = start;
926+ for i in start..end {
927+ // add backslash for escaped characters.
928+ let c = match value[ i] {
929+ 0x5C => "\\ \\ " ,
930+ 0x22 => "\\ \" " ,
931+ 0x2F => "\\ /" ,
932+ 0x08 => "\\ b" ,
933+ 0x0C => "\\ f" ,
934+ 0x0A => "\\ n" ,
935+ 0x0D => "\\ r" ,
936+ 0x09 => "\\ t" ,
937+ _ => {
938+ continue ;
939+ }
940+ } ;
941+ if i > last_start {
942+ let val = unsafe { std:: str:: from_utf8_unchecked ( & value[ last_start..i] ) } ;
943+ json. push_str ( val) ;
944+ }
945+ json. push_str ( c) ;
946+ last_start = i + 1 ;
947+ }
948+ if last_start < end {
949+ let val = unsafe { std:: str:: from_utf8_unchecked ( & value[ last_start..end] ) } ;
950+ json. push_str ( val) ;
951+ }
952+ json. push ( '\"' ) ;
953+ }
954+
929955// Check whether the value is `JSONB` format,
930956// for compatibility with previous `JSON` string.
931957fn is_jsonb ( value : & [ u8 ] ) -> bool {
0 commit comments