Skip to content

Commit 47009e4

Browse files
committed
added an escape_solidus option to the initialize() routines. This is used to specify whether the forward slash "/" is escaped when serializing JSON. By default, this is now False, which changes the behavior introduced in 6.0.0 (where the slashes were always escaped). Note that both options are valid JSON.
Fixes #304
1 parent 68df006 commit 47009e4

File tree

4 files changed

+60
-18
lines changed

4 files changed

+60
-18
lines changed

src/json_file_module.F90

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,8 @@ subroutine initialize_json_core_in_file(me,verbose,compact_reals,&
339339
path_mode,&
340340
path_separator,&
341341
compress_vectors,&
342-
allow_duplicate_keys)
342+
allow_duplicate_keys,&
343+
escape_solidus)
343344

344345
implicit none
345346

@@ -357,7 +358,8 @@ subroutine initialize_json_core_in_file(me,verbose,compact_reals,&
357358
path_mode,&
358359
path_separator,&
359360
compress_vectors,&
360-
allow_duplicate_keys)
361+
allow_duplicate_keys,&
362+
escape_solidus)
361363

362364
end subroutine initialize_json_core_in_file
363365
!*****************************************************************************************
@@ -422,7 +424,8 @@ function initialize_json_file(p,verbose,compact_reals,&
422424
path_mode,&
423425
path_separator,&
424426
compress_vectors,&
425-
allow_duplicate_keys) result(file_object)
427+
allow_duplicate_keys,&
428+
escape_solidus) result(file_object)
426429

427430
implicit none
428431

@@ -442,7 +445,8 @@ function initialize_json_file(p,verbose,compact_reals,&
442445
path_mode,&
443446
path_separator,&
444447
compress_vectors,&
445-
allow_duplicate_keys)
448+
allow_duplicate_keys,&
449+
escape_solidus)
446450

447451
if (present(p)) file_object%p => p
448452

src/json_initialize_arguments.inc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,11 @@ logical(LK),intent(in),optional :: allow_duplicate_keys
6666
!! keys are found, an error is thrown. A call to
6767
!! [[json_value_validate]] will also check for
6868
!! duplicates.
69+
logical(LK),intent(in),optional :: escape_solidus
70+
!! * If True then the solidus "`/`" is always escaped
71+
!! "`\/`" when serializing JSON
72+
!! * If False [default], then it is not escaped.
73+
!! Note that this option does not affect parsing
74+
!! (both escaped and unescaped are still valid in
75+
!! all cases).
76+

src/json_string_utilities.F90

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,12 +293,14 @@ end subroutine compact_real_string
293293
!
294294
! Add the escape characters to a string for adding to JSON.
295295

296-
subroutine escape_string(str_in, str_out)
296+
subroutine escape_string(str_in, str_out, escape_solidus)
297297

298298
implicit none
299299

300300
character(kind=CK,len=*),intent(in) :: str_in
301301
character(kind=CK,len=:),allocatable,intent(out) :: str_out
302+
logical(LK),intent(in) :: escape_solidus !! if the solidus (forward slash)
303+
!! is also to be escaped
302304

303305
integer(IK) :: i !! counter
304306
integer(IK) :: ipos !! accumulated string size
@@ -308,20 +310,29 @@ subroutine escape_string(str_in, str_out)
308310
#if defined __GFORTRAN__
309311
character(kind=CK,len=:),allocatable :: tmp !! workaround for bug in gfortran 6.1
310312
#endif
313+
logical :: to_be_escaped !! if there are characters to be escaped
311314

312-
character(kind=CK,len=*),parameter :: specials = quotation_mark//&
315+
character(kind=CK,len=*),parameter :: specials_no_slash = quotation_mark//&
313316
backslash//&
314-
slash//&
315317
bspace//&
316318
formfeed//&
317319
newline//&
318320
carriage_return//&
319321
horizontal_tab
320322

323+
character(kind=CK,len=*),parameter :: specials = specials_no_slash//slash
324+
325+
321326
!Do a quick scan for the special characters,
322327
! if any are present, then process the string,
323328
! otherwise, return the string as is.
324-
if (scan(str_in,specials)>0) then
329+
if (escape_solidus) then
330+
to_be_escaped = scan(str_in,specials)>0
331+
else
332+
to_be_escaped = scan(str_in,specials_no_slash)>0
333+
end if
334+
335+
if (to_be_escaped) then
325336

326337
str_out = repeat(space,chunk_size)
327338
ipos = 1
@@ -351,9 +362,14 @@ subroutine escape_string(str_in, str_out)
351362
str_out(ipos:ipos+1) = backslash//c
352363
ipos = ipos + 2
353364

354-
case(quotation_mark,slash)
365+
case(quotation_mark)
355366
str_out(ipos:ipos+1) = backslash//c
356367
ipos = ipos + 2
368+
case(slash)
369+
if (escape_solidus) then
370+
str_out(ipos:ipos+1) = backslash//c
371+
ipos = ipos + 2
372+
end if
357373
case(bspace)
358374
str_out(ipos:ipos+1) = '\b'
359375
ipos = ipos + 2

src/json_value_module.F90

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,13 @@ module json_value_module
237237
!! will also check for duplicates. If True
238238
!! [default] then no special checks are done
239239

240+
logical(LK) :: escape_solidus = .false. !! If True then the solidus "`/`" is always escaped
241+
!! ("`\/`") when serializing JSON.
242+
!! If False [default], then it is not escaped.
243+
!! Note that this option does not affect parsing
244+
!! (both escaped and unescaped versions are still
245+
!! valid in all cases).
246+
240247
contains
241248

242249
private
@@ -792,7 +799,8 @@ function initialize_json_core(verbose,compact_reals,&
792799
path_mode,&
793800
path_separator,&
794801
compress_vectors,&
795-
allow_duplicate_keys) result(json_core_object)
802+
allow_duplicate_keys,&
803+
escape_solidus) result(json_core_object)
796804

797805
implicit none
798806

@@ -810,7 +818,8 @@ function initialize_json_core(verbose,compact_reals,&
810818
path_mode,&
811819
path_separator,&
812820
compress_vectors,&
813-
allow_duplicate_keys)
821+
allow_duplicate_keys,&
822+
escape_solidus)
814823

815824
end function initialize_json_core
816825
!*****************************************************************************************
@@ -845,7 +854,8 @@ subroutine json_initialize(me,verbose,compact_reals,&
845854
path_mode,&
846855
path_separator,&
847856
compress_vectors,&
848-
allow_duplicate_keys)
857+
allow_duplicate_keys,&
858+
escape_solidus)
849859

850860
implicit none
851861

@@ -923,6 +933,11 @@ subroutine json_initialize(me,verbose,compact_reals,&
923933
me%allow_duplicate_keys = allow_duplicate_keys
924934
end if
925935

936+
! if escaping the forward slash:
937+
if (present(escape_solidus)) then
938+
me%escape_solidus = escape_solidus
939+
end if
940+
926941
!Set the format for real numbers:
927942
! [if not changing it, then it remains the same]
928943

@@ -1975,7 +1990,7 @@ recursive subroutine json_value_destroy(json,p,destroy_next)
19751990
if (associated(child)) then
19761991
p%children => p%children%next
19771992
p%n_children = p%n_children - 1
1978-
call json_value_destroy(json,child,.false.)
1993+
call json%destroy(child,.false.)
19791994
else
19801995
call json%throw_exception('Error in json_value_destroy: '//&
19811996
'Malformed JSON linked list')
@@ -1986,7 +2001,7 @@ recursive subroutine json_value_destroy(json,p,destroy_next)
19862001
nullify(child)
19872002
end if
19882003

1989-
if (associated(p%next) .and. des_next) call json_value_destroy(json,p%next)
2004+
if (associated(p%next) .and. des_next) call json%destroy(p%next)
19902005

19912006
if (associated(p%previous)) nullify(p%previous)
19922007
if (associated(p%parent)) nullify(p%parent)
@@ -2418,7 +2433,6 @@ subroutine json_value_validate(json,p,is_valid,error_msg)
24182433
logical(LK) :: has_duplicate !! to check for duplicate keys
24192434
character(kind=CK,len=:),allocatable :: path !! path to duplicate key
24202435
logical(LK) :: status_ok !! to check for existing exception
2421-
logical(LK) :: status_ok2 !! to check for a new exception
24222436
character(kind=CK,len=:),allocatable :: exception_msg !! error message for an existing exception
24232437
character(kind=CK,len=:),allocatable :: exception_msg2 !! error message for a new exception
24242438

@@ -5257,7 +5271,7 @@ recursive subroutine json_value_print(json,p,iunit,str,indent,&
52575271

52585272
! print the name
52595273
if (allocated(element%name)) then
5260-
call escape_string(element%name,str_escaped)
5274+
call escape_string(element%name,str_escaped,json%escape_solidus)
52615275
if (json%no_whitespace) then
52625276
!compact printing - no extra space
52635277
call write_it(repeat(space, spaces)//quotation_mark//&
@@ -5384,7 +5398,7 @@ recursive subroutine json_value_print(json,p,iunit,str,indent,&
53845398

53855399
if (allocated(p%str_value)) then
53865400
! have to escape the string for printing:
5387-
call escape_string(p%str_value,str_escaped)
5401+
call escape_string(p%str_value,str_escaped,json%escape_solidus)
53885402
call write_it( s//quotation_mark// &
53895403
str_escaped//quotation_mark, &
53905404
comma=print_comma, &
@@ -7678,7 +7692,7 @@ subroutine json_get_string(json, me, value)
76787692
value = me%str_value
76797693
else
76807694
! return the escaped version:
7681-
call escape_string(me%str_value, value)
7695+
call escape_string(me%str_value, value, json%escape_solidus)
76827696
end if
76837697
else
76847698
call json%throw_exception('Error in json_get_string: '//&

0 commit comments

Comments
 (0)