@@ -528,17 +528,17 @@ there is no exponent here.")
528528 (let-do [c (Cursor.advance cur \")
529529 bytes (the (Array Byte) [])
530530 going true
531- err false ]
532- (while-do (and going (not err))
531+ err @"" ]
532+ (while-do (and going (Int.= 0 (String.length & err) ))
533533 (if (Int.>= @(Cursor.pos &c) len)
534- (set! err true )
534+ (set! err @"closing quote" )
535535 (let [ch (String.char-at src @(Cursor.pos &c))]
536536 (cond
537537 (Char.= ch \")
538538 (do (set! c (Cursor.advance &c ch)) (set! going false))
539539 (Char.= ch \\)
540540 (if (Int.>= (Int.+ @(Cursor.pos &c) 1) len)
541- (set! err true )
541+ (set! err @"closing quote" )
542542 (let [esc (String.char-at src
543543 (Int.+ @(Cursor.pos &c) 1))]
544544 (cond
@@ -600,40 +600,49 @@ there is no exponent here.")
600600 (Int.- end
601601 @(Cursor.pos &c))
602602 false)))
603- (set! err true )))
603+ (set! err @"hex digits after \\x" )))
604604 (Char.= esc \u)
605605 (if (Int.>= (Int.+ @(Cursor.pos &c) 6)
606606 (Int.inc len))
607- (set! err true)
608- (do
609- (set! bytes
610- (push-utf8-bytes bytes
611- (read-hex src
612- (Int.+ @(Cursor.pos &c)
613- 2)
614- 4)))
615- (set! c (Cursor.advance-by &c 6 false))))
607+ (set! err @"4 hex digits in \\u escape")
608+ (let-do [hex-start (Int.+ @(Cursor.pos &c) 2)
609+ all-hex true]
610+ (for [j hex-start (Int.+ hex-start 4)]
611+ (unless (hex-digit? (String.char-at src j))
612+ (set! all-hex false)))
613+ (if all-hex
614+ (do
615+ (set! bytes
616+ (push-utf8-bytes bytes
617+ (read-hex src
618+ hex-start
619+ 4)))
620+ (set! c (Cursor.advance-by &c 6 false)))
621+ (set! err @"hex digits in \\u escape"))))
616622 (Char.= esc \U)
617623 (if (Int.>= (Int.+ @(Cursor.pos &c) 10)
618624 (Int.inc len))
619- (set! err true)
620- (do
621- (set! bytes
622- (push-utf8-bytes bytes
623- (read-hex src
624- (Int.+ @(Cursor.pos &c)
625- 2)
626- 8)))
627- (set! c (Cursor.advance-by &c 10 false))))
628- (do
629- (set! bytes (push-byte bytes \\))
630- (set! bytes (push-byte bytes esc))
631- (set! c (Cursor.advance-by &c 2 false))))))
625+ (set! err @"8 hex digits in \\U escape")
626+ (let-do [hex-start (Int.+ @(Cursor.pos &c) 2)
627+ all-hex true]
628+ (for [j hex-start (Int.+ hex-start 8)]
629+ (unless (hex-digit? (String.char-at src j))
630+ (set! all-hex false)))
631+ (if all-hex
632+ (do
633+ (set! bytes
634+ (push-utf8-bytes bytes
635+ (read-hex src
636+ hex-start
637+ 8)))
638+ (set! c (Cursor.advance-by &c 10 false)))
639+ (set! err @"hex digits in \\U escape"))))
640+ (set! err @"valid escape sequence"))))
632641 (do
633642 (set! bytes (push-byte bytes ch))
634643 (set! c (Cursor.advance &c ch)))))))
635- (if err
636- (Reply.ErrConsumed (ParseErr.expected-at &c @"closing quote" ))
644+ (if (Int.> (String.length & err) 0)
645+ (Reply.ErrConsumed (ParseErr.expected-at &c err ))
637646 (Reply.OkConsumed (Form.Str (String.from-bytes &bytes)) c))))))))
638647
639648 (private raw-string)
0 commit comments