@@ -165,8 +165,8 @@ public JsonType peek() {
165165 return JsonType .END ;
166166
167167 default :
168- char c = input .read ();
169- throw new JsonException ("Unable to determine type from: " + c + ". " + input );
168+ int c = input .read ();
169+ throw new JsonException ("Unable to determine type from: " + ( char ) c + ". " + input );
170170 }
171171 }
172172
@@ -194,10 +194,10 @@ public String nextName() {
194194
195195 String name = readString ();
196196 skipWhitespace (input );
197- char read = input .read ();
197+ int read = input .read ();
198198 if (read != ':' ) {
199199 throw new JsonException (
200- "Unable to read name. Expected colon separator, but saw '" + read + "'" );
200+ "Unable to read name. Expected colon separator, but saw '" + ( char ) read + "'" );
201201 }
202202 return name ;
203203 }
@@ -241,13 +241,13 @@ public Number nextNumber() {
241241 case '7' :
242242 case '8' :
243243 case '9' :
244- builder .append (input .read ());
244+ builder .append (( char ) input .read ());
245245 break ;
246246 case '.' :
247247 case 'e' :
248248 case 'E' :
249249 mightBeDecimal = true ;
250- builder .append (input .read ());
250+ builder .append (( char ) input .read ());
251251 break ;
252252 default :
253253 read = false ;
@@ -552,11 +552,11 @@ private void expect(JsonType type) {
552552
553553 int toCompareLength = toCompare .length ();
554554 for (int i = 0 ; i < toCompareLength ; i ++) {
555- char read = input .read ();
555+ int read = input .read ();
556556 if (read != toCompare .charAt (i )) {
557557 throw new JsonException (
558558 String .format (
559- "Unable to read %s. Saw %s at position %d. %s" , toCompare , read , i , input ));
559+ "Unable to read %s. Saw %s at position %d. %s" , toCompare , ( char ) read , i , input ));
560560 }
561561 }
562562
@@ -574,9 +574,8 @@ private String readString() {
574574 input .read (); // Skip leading quote
575575
576576 StringBuilder builder = new StringBuilder ();
577- char c ;
578577 while (true ) {
579- c = input .read ();
578+ int c = input .read ();
580579 switch (c ) {
581580 case Input .EOF :
582581 throw new JsonException ("Unterminated string: " + builder + ". " + input );
@@ -586,7 +585,13 @@ private String readString() {
586585 readEscape (builder );
587586 break ;
588587 default :
589- builder .append (c );
588+ // RFC 8259 §7: characters U+0000..U+001F MUST be escaped.
589+ if (c < 0x20 ) {
590+ throw new JsonException (
591+ String .format (
592+ "Illegal unescaped control character U+%04X in string. %s" , c , input ));
593+ }
594+ builder .append ((char ) c );
590595 }
591596 }
592597 }
@@ -601,7 +606,7 @@ private String readString() {
601606 */
602607 // FIXME: This function doesn't appear to support UTF-8 or UTF-32.
603608 private void readEscape (StringBuilder builder ) {
604- char read = input .read ();
609+ int read = input .read ();
605610
606611 // List from: https://tools.ietf.org/html/rfc7159.html#section-7
607612 switch (read ) {
@@ -629,10 +634,10 @@ private void readEscape(StringBuilder builder) {
629634 int result = 0 ;
630635 int multiplier = 4096 ; // (16 * 16 * 16) as we start from the thousands and work to units.
631636 for (int i = 0 ; i < 4 ; i ++) {
632- char c = input .read ();
637+ int c = input .read ();
633638 int digit = Character .digit (c , 16 );
634639 if (digit == -1 ) {
635- throw new JsonException (c + " is not a hexadecimal digit. " + input );
640+ throw new JsonException (( char ) c + " is not a hexadecimal digit. " + input );
636641 }
637642 result += digit * multiplier ;
638643 multiplier /= 16 ;
@@ -643,11 +648,11 @@ private void readEscape(StringBuilder builder) {
643648 case '/' :
644649 case '\\' :
645650 case '"' :
646- builder .append (read );
651+ builder .append (( char ) read );
647652 break ;
648653
649654 default :
650- throw new JsonException ("Unexpected escape code: " + read + ". " + input );
655+ throw new JsonException ("Unexpected escape code: " + ( char ) read + ". " + input );
651656 }
652657 }
653658
0 commit comments