@@ -3466,6 +3466,7 @@ recursive subroutine parse_object(unit, parent)
34663466 else if (' "' == c) then
34673467 call json_value_create(pair)
34683468 call parse_string(unit, pair % name)
3469+ if (exception_thrown) return
34693470 else
34703471 call throw_exception(' Error in parse_object: Expecting string: "' // c// ' "' )
34713472 call cleanup()
@@ -3481,6 +3482,7 @@ recursive subroutine parse_object(unit, parent)
34813482 else if (' :' == c) then
34823483 ! parse the value
34833484 call parse_value(unit, pair)
3485+ if (exception_thrown) return
34843486 call json_value_add(parent, pair)
34853487 else
34863488 call throw_exception(' Error in parse_object: Expecting : and then a value: ' // c)
@@ -3551,6 +3553,7 @@ recursive subroutine parse_array(unit, array)
35513553 ! try to parse an element value
35523554 call json_value_create(element)
35533555 call parse_value(unit, element)
3556+ if (exception_thrown) return
35543557
35553558 ! parse value will disassociate an empty array value
35563559 if (associated (element)) then
@@ -3566,6 +3569,7 @@ recursive subroutine parse_array(unit, array)
35663569 else if (' ,' == c) then
35673570 ! parse the next element
35683571 call parse_array(unit, array)
3572+ if (exception_thrown) return
35693573 else if (' ]' == c) then
35703574 ! end of array
35713575 return
@@ -3583,7 +3587,10 @@ end subroutine parse_array
35833587! parse_string
35843588!
35853589! DESCRIPTION
3590+ ! Parses a string while reading a json file
35863591!
3592+ ! HISTORY
3593+ ! JW : 6/16/2014 : added hex validation.
35873594!
35883595! SOURCE
35893596
@@ -3594,25 +3601,74 @@ subroutine parse_string(unit, string)
35943601 integer , intent (in ) :: unit
35953602 character (len= :),allocatable ,intent (out ) :: string
35963603
3597- logical :: eof
3604+ logical :: eof, is_hex, escape
35983605 character (len= 1 ) :: c, last
3606+ character (len= 4 ) :: hex
3607+ integer :: i
35993608
36003609 if (.not. exception_thrown) then
36013610
3602- string = ' ' ! initialize string
3603- last = ' ' !
3604-
3611+ ! initialize:
3612+ string = ' '
3613+ last = space
3614+ is_hex = .false.
3615+ escape = .false.
3616+ i = 0
3617+
36053618 do
3619+
3620+ ! get the next character from the file:
36063621 c = pop_char(unit, eof = eof, skip_ws = .false. )
3622+
36073623 if (eof) then
3624+
36083625 call throw_exception(' Error in parse_string: Expecting end of string' )
36093626 return
3627+
36103628 else if (' "' == c .and. last /= ' \' ) then
3629+
3630+ if (is_hex) call throw_exception(' Error in parse_string: incomplete hex string: \u' // trim (hex))
36113631 exit
3632+
36123633 else
3634+
3635+ ! append to string:
3636+ string = string// c
3637+
3638+ ! hex validation:
3639+ if (is_hex) then ! accumulate the four characters after '\u'
3640+
3641+ i= i+1
3642+ hex(i:i) = c
3643+ if (i== 4 ) then
3644+ if (valid_json_hex(hex)) then
3645+ i = 0
3646+ hex = ' '
3647+ is_hex = .false.
3648+ else
3649+ call throw_exception(' Error in parse_string: invalid hex string: \u' // trim (hex))
3650+ exit
3651+ end if
3652+ end if
3653+
3654+ else
3655+
3656+ ! when the '\u' string is encountered, then
3657+ ! start accumulating the hex string (should be the next 4 characters)
3658+ if (escape) then
3659+ escape = .false.
3660+ is_hex = (c==' u' ) ! the next four characters are the hex string
3661+ else
3662+ escape = (c==' \' )
3663+ end if
3664+
3665+ end if
3666+
3667+ ! update for next char:
36133668 last = c
3614- string = string // c ! append to string
3669+
36153670 end if
3671+
36163672 end do
36173673
36183674 end if
0 commit comments