Skip to content

Commit 47cb0e0

Browse files
committed
-added hex validation when reading a string from a json file.
1 parent 6d7648e commit 47cb0e0

File tree

1 file changed

+61
-5
lines changed

1 file changed

+61
-5
lines changed

src/json_module.f90

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)