# Copyright (C) 2016, 2017, 2018, 2019, 2020, 2021  Stefan Vargyas
# 
# This file is part of Json-Type.
# 
# Json-Type is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# Json-Type is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with Json-Type.  If not, see <http://www.gnu.org/licenses/>.

#
# json bugs test suite:
#

$ . ~/regtest2.sh
$ alias json-bugs-regtest='regtest2-selftest -f test-json-bugs.txt -a exec=pipe -B'

# output all test names:
$ json-bugs-regtest -N
...

# run all tests:
$ json-bugs-regtest -A
...

$ json-bugs-regtest -VArt > json-bugs-regtest.output
$ diff -u -Lold json-bugs-regtest.output -Lnew <(json-bugs-regtest -VArt)|diffview

--[ prereq ]--------------------------------------------------------------------

$ json() { set -o pipefail && LD_LIBRARY_PATH=../lib ../src/json --terse --verbose --literal-value "$@" 2>&1|sed -r '/error:/s|(/dev/fd/)[0-9]+|\1??|'; }
$

--[ 0 ]-------------------------------------------------------------------------

# [FIXED]
# the JSON input has a correct type yet the type checking fails
$ json -t <(echo '{"type":"list","args":["number",{"type":"array","args":"number"}]}') <<< '[1]'
[1]
$

--[ 1 ]-------------------------------------------------------------------------

$ json -t <(echo '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":{"type":"object","args":[]}}]}]}') <<< '{"foo":false}'
{"foo":false}
$ json -t <(echo '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":{"type":"object","args":[]}}]}]}') <<< '{"foo":{"bar":0}}'
json: error: <stdin>:1:9: type check error: too many arguments
json: error: <stdin>:1:9: {"foo":{"bar":0}}
json: error: <stdin>:1:9:         ^
{"foo":{
command failed: json -t <(echo '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":{"type":"object","args":[]}}]}]}') <<< '{"foo":{"bar":0}}'
# [FIXED]
# the JSON input has a correct type yet the type checking fails
$ json -t <(echo '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":{"type":"object","args":[]}}]}]}') <<< '{"foo":{}}'
{"foo":{}}
$

--[ 2 ]-------------------------------------------------------------------------

$ json -t <(echo '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":[]}}]}]}') <<< '{"foo":false}'
{"foo":false}
$ json -t <(echo '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":[]}}]}]}') <<< '{"foo":[0]}'
json: error: <stdin>:1:9: type check error: too many arguments
json: error: <stdin>:1:9: {"foo":[0]}
json: error: <stdin>:1:9:         ^
{"foo":[
command failed: json -t <(echo '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":[]}}]}]}') <<< '{"foo":[0]}'
# [FIXED]
# the JSON input has a correct type yet the type checking fails
$ json -t <(echo '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":[]}}]}]}') <<< '{"foo":[]}'
{"foo":[]}
$

--[ 3 ]-------------------------------------------------------------------------

$ json -t <(echo '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":["number"]}}]}]}') <<< '{"foo":false}'
json: error: /dev/fd/??:1:129: type lib error: attribute error: invalid "list" type object: sort of object of array type not yet supported (the other inner array is at 1:205)
command failed: json -t <(echo '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":["number"]}}]}]}') <<< '{"foo":false}'
$ json -t <(echo '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":["number"]}}]}]}') <<< '{"foo":[]}'
json: error: /dev/fd/??:1:129: type lib error: attribute error: invalid "list" type object: sort of object of array type not yet supported (the other inner array is at 1:205)
command failed: json -t <(echo '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":["number"]}}]}]}') <<< '{"foo":[]}'
# [FIXED]
# the JSON input has a correct type yet the type checking fails
$ json -t <(echo '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":["number"]}}]}]}') <<< '{"foo":[1]}'
json: error: /dev/fd/??:1:129: type lib error: attribute error: invalid "list" type object: sort of object of array type not yet supported (the other inner array is at 1:205)
command failed: json -t <(echo '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":["number"]}}]}]}') <<< '{"foo":[1]}'
$

--[ 4 ]-------------------------------------------------------------------------

# [FIXED]
# the JSON input has a correct type yet the type checking fails
$ json -t <(echo '{"type":"list","args":[{"type":"array","args":[{"plain":0}]}]}') <<< '[0]'
[0]
$

--[ 5 ]-------------------------------------------------------------------------

# [FIXED]
# the JSON input has a correct type yet the type checking fails
$ json -t <(echo '{"type":"list","args":[{"type":"array","args":[{"plain":0},{"plain":1}]}]}') <<< '[0,1]'
[0,1]
$

--[ 6 ]-------------------------------------------------------------------------

# [FIXED]
# the JSON input below should have passed the type checking successfully
$ json -d '{"type":"object","args":[{"name":"foo","type":{"type":"list","args":[{"type":"array","args":[]},{"type":"array","args":["number"]}]}}]}' <<< '{"foo":[1]}'
{"foo":[1]}
$

--[ 7 ]-------------------------------------------------------------------------

# [FIXED]
# the bug above can be narrowed down to the following invocation
$ json -d '{"type":"list","args":[{"type":"array","args":[]},{"type":"array","args":["number"]}]}' <<< '[1]'
[1]
$

--[ 8 ]-------------------------------------------------------------------------

# [FIXED]
# this one belongs to the same category as the above
$ json -d '{"type":"list","args":[{"type":"array","args":["number"]},{"type":"array","args":["number","number"]}]}' <<< '[1,2]'
[1,2]
$

--[ 9 ]-------------------------------------------------------------------------

# [FIXED]
# the JSON input shouldn't have passed type checking
$ json -d '{"type":"list","args":[{"type":"array","args":"number"},{"type":"array","args":"string"}]}' <<< '[1,""]'
json: error: <stdin>:1:4: type check error: type mismatch: expected a value of type `"number"'
json: error: <stdin>:1:4: [1,""]
json: error: <stdin>:1:4:    ^
[1,
command failed: json -d '{"type":"list","args":[{"type":"array","args":"number"},{"type":"array","args":"string"}]}' <<< '[1,""]'
$

--[ 10 ]------------------------------------------------------------------------

# [FIXED]
# the JSON input below should have passed the type checking successfully
$ json -d '{"type":"list","args":[{"type":"array","args":"number"},{"type":"array","args":"string"},{"type":"array","args":["number","string"]}]}' <<< '[1,2]'
[1,2]
$

--[ 11 ]------------------------------------------------------------------------

# [FIXED]
# the following type definition is ambiguous and must be rejected
$ json -Tc <<< '{"type":"list","args":[{"type":"array","args":"number"},{"type":"array","args":{"plain":1}}]}'
json: error: <stdin>:1:80: attribute error: invalid "list" type object: array argument ambiguity (the other is at 1:47)
json: error: <stdin>:1:80: number"},{"type":"array","args":{"plain":1}}]}
json: error: <stdin>:1:80:                                 ^
command failed: json -Tc <<< '{"type":"list","args":[{"type":"array","args":"number"},{"type":"array","args":{"plain":1}}]}'
## # stev: 2016-04-07 13:52:21: not sure anymore that the behavior above is indeed a bug
## $ json -d '{"type":"list","args":[{"type":"array","args":"number"},{"type":"array","args":{"plain":1}}]}' <<< '[0]' 
## [0]
## $ json -d '{"type":"list","args":[{"type":"array","args":"number"},{"type":"array","args":{"plain":1}}]}' <<< '[1]' 
## [1]
## # stev: 2016-04-09 17:35:32: taking into account the outputs below, we have indeed a bug! --
## # and indeed the type definition must be rejected!
## $ json -d '{"type":"list","args":[{"type":"array","args":"number"},{"type":"array","args":{"plain":1}}]}' <<< '[1,1]'
## [1,1]
## $ json -d '{"type":"list","args":[{"type":"array","args":"number"},{"type":"array","args":{"plain":1}}]}' <<< '[1,2]'
## json: error: <stdin>:1:4: type check error: type mismatch: expected a value of type `{"plain":1}'
## json: error: <stdin>:1:4: [1,2]
## json: error: <stdin>:1:4:    ^
## [1,
## command failed: json -d '{"type":"list","args":[{"type":"array","args":"number"},{"type":"array","args":{"plain":1}}]}' <<< '[1,2]'
$

--[ 12 ]------------------------------------------------------------------------

# [FIXED]
# the JSON input below should have passed the type checking successfully
$ json -d '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"number"}]},{"type":"object","args":[{"name":"foo","type":"number"},{"name":"bar","type":"number"}]}]}' <<< '{"foo":0,"bar":1}'
{"foo":0,"bar":1}
$

--[ 13 ]------------------------------------------------------------------------

# [FIXED]
# the following type definition is ambiguous and must be rejected
$ json -Tc <<< '{"type":"list","args":[{"type":"array","args":"type"},{"type":"array","args":"array"}]}'
json: error: <stdin>:1:47: attribute error: invalid "list" type object: array argument ambiguity (the other is at 1:78)
json: error: <stdin>:1:47: ,"args":[{"type":"array","args":"type"},{"type":"array","args":"a
json: error: <stdin>:1:47:                                 ^
command failed: json -Tc <<< '{"type":"list","args":[{"type":"array","args":"type"},{"type":"array","args":"array"}]}'
$

--[ 14 ]------------------------------------------------------------------------

# [FIXED]
# the following type definition is ambiguous and must be rejected
$ json -Tc <<< '{"type":"list","args":[{"type":"array","args":["type","boolean"]},{"type":"array","args":["array","number"]}]}'
json: error: <stdin>:1:48: attribute error: invalid "list" type object: array argument ambiguity (the other is at 1:91)
json: error: <stdin>:1:48: "args":[{"type":"array","args":["type","boolean"]},{"type":"array
json: error: <stdin>:1:48:                                 ^
command failed: json -Tc <<< '{"type":"list","args":[{"type":"array","args":["type","boolean"]},{"type":"array","args":["array","number"]}]}'
$

--[ 15 ]------------------------------------------------------------------------

# [FIXED]
# the following type definition is ambiguous and must be rejected
$ json -Tc <<< '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"type"},{"name":"bar","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":"array"},{"name":"bar","type":"number"}]}]}'
json: error: <stdin>:1:70: attribute error: invalid "list" type object: object argument ambiguity (the other is at 1:158)
json: error: <stdin>:1:70: t","args":[{"name":"foo","type":"type"},{"name":"bar","type":"boo
json: error: <stdin>:1:70:                                 ^
command failed: json -Tc <<< '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":"type"},{"name":"bar","type":"boolean"}]},{"type":"object","args":[{"name":"foo","type":"array"},{"name":"bar","type":"number"}]}]}'
$

--[ 16 ]------------------------------------------------------------------------

# note that the bug below belong to the same category as bug #3
# [FIXED]
# the type def below is not ambiguous, yet the type checking fails
$ json -d '{"type":"list","args":[{"type":"array","args":{"type":"array","args":"number"}},{"type":"array","args":{"type":"array","args":"string"}}]}' <<< '[[""]]'
json: error: <text>:1:47: type lib error: attribute error: invalid "list" type object: sort of array of array type not yet supported (the other inner array is at 1:104)
command failed: json -d '{"type":"list","args":[{"type":"array","args":{"type":"array","args":"number"}},{"type":"array","args":{"type":"array","args":"string"}}]}' <<< '[[""]]'
# note that a similar attribute error is got for the following two type definitions, even if the inputs are correctly typed:
$ json -d '{"type":"list","args":[{"type":"array","args":{"type":"array","args":["number"]}},{"type":"array","args":{"type":"array","args":["string"]}}]}' <<< '[[""]]'
json: error: <text>:1:47: type lib error: attribute error: invalid "list" type object: sort of array of array type not yet supported (the other inner array is at 1:106)
command failed: json -d '{"type":"list","args":[{"type":"array","args":{"type":"array","args":["number"]}},{"type":"array","args":{"type":"array","args":["string"]}}]}' <<< '[[""]]'
$ json -d '{"type":"list","args":[{"type":"array","args":{"type":"object","args":[{"name":"foo","type":"number"}]}},{"type":"array","args":{"type":"object","args":[{"name":"foo","type":"string"}]}}]}' <<< '[{"foo":""}]'
json: error: <text>:1:47: type lib error: attribute error: invalid "list" type object: sort of array of object type not yet supported (the other inner object is at 1:129)
command failed: json -d '{"type":"list","args":[{"type":"array","args":{"type":"object","args":[{"name":"foo","type":"number"}]}},{"type":"array","args":{"type":"object","args":[{"name":"foo","type":"string"}]}}]}' <<< '[{"foo":""}]'
$ json -d '{"type":"list","args":[{"type":"array","args":{"type":"object","args":[{"name":"foo","type":"number"}]}},{"type":"array","args":{"type":"object","args":[{"name":"bar","type":"string"}]}}]}' <<< '[{"bar":""}]'
json: error: <text>:1:129: type lib error: attribute error: invalid "list" type object: sort of array of object type not yet supported (the other inner object is at 1:47)
command failed: json -d '{"type":"list","args":[{"type":"array","args":{"type":"object","args":[{"name":"foo","type":"number"}]}},{"type":"array","args":{"type":"object","args":[{"name":"bar","type":"string"}]}}]}' <<< '[{"bar":""}]'
$ json -d '{"type":"list","args":[{"type":"array","args":["boolean",{"type":"array","args":"number"}]},{"type":"array","args":["boolean",{"type":"array","args":"string"}]}]}' <<< '[false,[""]]'
json: error: <text>:1:58: type lib error: attribute error: invalid "list" type object: sort of array of array type not yet supported (the other inner array is at 1:127)
command failed: json -d '{"type":"list","args":[{"type":"array","args":["boolean",{"type":"array","args":"number"}]},{"type":"array","args":["boolean",{"type":"array","args":"string"}]}]}' <<< '[false,[""]]'
$

--[ 17 ]------------------------------------------------------------------------

# [FIXED]
# apparently correct JSON input yet it is rejected; this is in fact an ambiguity issue
$ json -d '{"type":"list","args":[{"type":"array","args":{"type":"list","args":["number"]}},{"type":"array","args":["number","number"]}]}' <<< '[1]'
json: error: <text>:1:24: type lib error: attribute error: invalid "list" type object: sort of array of list type not yet supported (the inner list is at 1:47)
command failed: json -d '{"type":"list","args":[{"type":"array","args":{"type":"list","args":["number"]}},{"type":"array","args":["number","number"]}]}' <<< '[1]'
# the same type of ambiguity as in the def below:
$ json -Tc <<< '{"type":"list","args":[{"type":"array","args":"number"},{"type":"array","args":["number","number"]}]}'
json: error: <stdin>:1:47: attribute error: invalid "list" type object: array ambiguity (the other defined at 1:57)
json: error: <stdin>:1:47: ,"args":[{"type":"array","args":"number"},{"type":"array","args":
json: error: <stdin>:1:47:                                 ^
command failed: json -Tc <<< '{"type":"list","args":[{"type":"array","args":"number"},{"type":"array","args":["number","number"]}]}'
$

--[ 18 ]------------------------------------------------------------------------

# [FIXED]
# the type def below should have been rejected as ambiguous
$ json -Tc <<< '{"type":"list","args":[{"type":"array","args":{"type":"list","args":["number"]}},{"type":"array","args":["number"]}]}'
json: error: <stdin>:1:24: attribute error: invalid "list" type object: sort of array of list type not yet supported (the inner list is at 1:47)
json: error: <stdin>:1:24: {"type":"list","args":[{"type":"array","args":{"type":"l
json: error: <stdin>:1:24:                        ^
command failed: json -Tc <<< '{"type":"list","args":[{"type":"array","args":{"type":"list","args":["number"]}},{"type":"array","args":["number"]}]}'
$

--[ 19 ]------------------------------------------------------------------------

# [FIXED]
# the type def below should have been rejected as ambiguous
$ json -d '{"type":"list","args":[{"type":"array","args":{"type":"array","args":"number"}},{"type":"array","args":{"type":"list","args":["number"]}}]}' <<< '[0]'
json: error: <text>:1:81: type lib error: attribute error: invalid "list" type object: sort of array of list type not yet supported (the inner list is at 1:104)
command failed: json -d '{"type":"list","args":[{"type":"array","args":{"type":"array","args":"number"}},{"type":"array","args":{"type":"list","args":["number"]}}]}' <<< '[0]'
$

--[ 20 ]------------------------------------------------------------------------

# [FIXED]
# correctly typed JSON input, yet
$ json -d '{"type":"list","args":[{"type":"array","args":{"type":"list","args":["number"]}}]}' <<< '[0]'
json: error: <text>:1:24: type lib error: attribute error: invalid "list" type object: sort of array of list type not yet supported (the inner list is at 1:47)
command failed: json -d '{"type":"list","args":[{"type":"array","args":{"type":"list","args":["number"]}}]}' <<< '[0]'
$

--[ 21 ]------------------------------------------------------------------------

# [FIXED]
# correctly types JSON input, yet
$ json -d '{"type":"list","args":[{"type":"array","args":{"type":"list","args":["number"]}}]}' <<< '[0,1]'
json: error: <text>:1:24: type lib error: attribute error: invalid "list" type object: sort of array of list type not yet supported (the inner list is at 1:47)
command failed: json -d '{"type":"list","args":[{"type":"array","args":{"type":"list","args":["number"]}}]}' <<< '[0,1]'
$

--[ 22 ]------------------------------------------------------------------------

# [FIXED]
# incorrect error message; it should have been: expected a value of type `"null"' or `"number"' or, otherwise, no value at all
$ json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number"]}]}' <<< '[false]'
json: error: <stdin>:1:2: type check error: type mismatch: expected a value of type `"null"' or `"number"' or, otherwise, no value at all
json: error: <stdin>:1:2: [false]
json: error: <stdin>:1:2:  ^
[
command failed: json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number"]}]}' <<< '[false]'
$

--[ 23 ]------------------------------------------------------------------------

$ json -d '{"type":"list","args":[{"type":"object","args":[{"name":"faa","type":"null"}]},{"type":"object","args":[]}]}' <<< '{"faa":null}'
{"faa":null}
$ json -d '{"type":"list","args":[{"type":"object","args":[{"name":"faa","type":"null"}]},{"type":"object","args":[]}]}' <<< '{"faa":false}'
json: error: <stdin>:1:8: type check error: type mismatch: expected a value of type `"null"'
json: error: <stdin>:1:8: {"faa":false}
json: error: <stdin>:1:8:        ^
{"faa":
command failed: json -d '{"type":"list","args":[{"type":"object","args":[{"name":"faa","type":"null"}]},{"type":"object","args":[]}]}' <<< '{"faa":false}'
# [FIXED]
# rejected correct JSON input
$ json -d '{"type":"list","args":[{"type":"object","args":[{"name":"faa","type":"null"}]},{"type":"object","args":[]}]}' <<< '{}'
{}
$

--[ 24 ]------------------------------------------------------------------------

$ json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[]'
[]
$ json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[null]'
[null]
$ json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[null,null]'
[null,null]
$ json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[null,null,null]'
[null,null,null]
$ json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[1]'
json: error: <stdin>:1:3: type check error: too few arguments
json: error: <stdin>:1:3: [1]
json: error: <stdin>:1:3:   ^
[1
command failed: json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[1]'
$ json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[1,false]'
json: error: <stdin>:1:4: type check error: type mismatch: expected a value of type `"number"'
json: error: <stdin>:1:4: [1,false]
json: error: <stdin>:1:4:    ^
[1,
command failed: json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[1,false]'
$ json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[1,1]'
[1,1]
$ json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[1,1,false]'
json: error: <stdin>:1:5: type check error: too many arguments
json: error: <stdin>:1:5: [1,1,false]
json: error: <stdin>:1:5:     ^
[1,1
command failed: json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[1,1,false]'
$ json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[1,1,1]'
json: error: <stdin>:1:5: type check error: too many arguments
json: error: <stdin>:1:5: [1,1,1]
json: error: <stdin>:1:5:     ^
[1,1
command failed: json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[1,1,1]'
$ json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[false]'
json: error: <stdin>:1:2: type check error: type mismatch: expected a value of type `"null"' or `"number"' or, otherwise, no value at all
json: error: <stdin>:1:2: [false]
json: error: <stdin>:1:2:  ^
[
command failed: json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[false]'
$ json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[null,false]'
json: error: <stdin>:1:7: type check error: type mismatch: expected a value of type `"null"'
json: error: <stdin>:1:7: [null,false]
json: error: <stdin>:1:7:       ^
[null,
command failed: json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[null,false]'
$ json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[null,null,false]'
json: error: <stdin>:1:12: type check error: type mismatch: expected a value of type `"null"'
json: error: <stdin>:1:12: [null,null,false]
json: error: <stdin>:1:12:            ^
[null,null,
command failed: json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[null,null,false]'
# [FIXED]
# incorrect JSON input which is not rejected
$ json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[null,1]'
json: error: <stdin>:1:7: type check error: type mismatch: expected a value of type `"null"'
json: error: <stdin>:1:7: [null,1]
json: error: <stdin>:1:7:       ^
[null,
command failed: json -d '{"type":"list","args":[{"type":"array","args":"null"},{"type":"array","args":["number","number"]}]}' <<< '[null,1]'
$

--[ 25 ]------------------------------------------------------------------------

## $ json -d '{"type":"list","args":[{"type":"array","args":["null"]},{"type":"array","args":{"plain":null}}]}' <<< '[]'
## []
## $ json -d '{"type":"list","args":[{"type":"array","args":["null"]},{"type":"array","args":{"plain":null}}]}' <<< '[null]'
## [null]
## # rejected correct JSON input
## $ json -d '{"type":"list","args":[{"type":"array","args":["null"]},{"type":"array","args":{"plain":null}}]}' <<< '[null,null]'
## [null,null]
## $ json -d '{"type":"list","args":[{"type":"array","args":["null"]},{"type":"array","args":{"plain":null}}]}' <<< '[null,null,null]'
## [null,null,null]
# [FIXED]
# stev: 2016-05-16 14:45:22: the type is rejected due to ambiguity:
$ json -Tc <<< '{"type":"list","args":[{"type":"array","args":["null"]},{"type":"array","args":{"plain":null}}]}'
json: error: <stdin>:1:80: attribute error: invalid "list" type object: array ambiguity (the other defined at 1:24)
json: error: <stdin>:1:80: "null"]},{"type":"array","args":{"plain":null}}]}
json: error: <stdin>:1:80:                                 ^
command failed: json -Tc <<< '{"type":"list","args":[{"type":"array","args":["null"]},{"type":"array","args":{"plain":null}}]}'
$

--[ 26 ]------------------------------------------------------------------------

$ json -d '{"type":"list","args":[{"type":"array","args":[]}]}' <<< '[]'
[]
# [FIXED]
# invalid JSON input: too few arguments
$ json -d '{"type":"list","args":[{"type":"array","args":["null"]}]}' <<< '[]'
json: error: <stdin>:1:2: type check error: too few arguments
json: error: <stdin>:1:2: []
json: error: <stdin>:1:2:  ^
[
command failed: json -d '{"type":"list","args":[{"type":"array","args":["null"]}]}' <<< '[]'
$

--[ 27 ]------------------------------------------------------------------------

# [FIXED]
# invalid JSON input: too few arguments
$ json -d '{"type":"list","args":[{"type":"array","args":["null","null"]}]}' <<< '[null]'
json: error: <stdin>:1:6: type check error: too few arguments
json: error: <stdin>:1:6: [null]
json: error: <stdin>:1:6:      ^
[null
command failed: json -d '{"type":"list","args":[{"type":"array","args":["null","null"]}]}' <<< '[null]'
$ json -d '{"type":"list","args":[{"type":"array","args":["null","null","null"]}]}' <<< '[null]'
json: error: <stdin>:1:6: type check error: too few arguments
json: error: <stdin>:1:6: [null]
json: error: <stdin>:1:6:      ^
[null
command failed: json -d '{"type":"list","args":[{"type":"array","args":["null","null","null"]}]}' <<< '[null]'
$ json -d '{"type":"list","args":[{"type":"array","args":["null","null","null"]}]}' <<< '[null,null]'
json: error: <stdin>:1:11: type check error: too few arguments
json: error: <stdin>:1:11: [null,null]
json: error: <stdin>:1:11:           ^
[null,null
command failed: json -d '{"type":"list","args":[{"type":"array","args":["null","null","null"]}]}' <<< '[null,null]'
$ json -d '{"type":"list","args":[{"type":"array","args":["null","null","null"]}]}' <<< '[null,null,null]'
[null,null,null]
$ json -d '{"type":"list","args":[{"type":"array","args":["null","null","null"]}]}' <<< '[null,null,null,null]' 
json: error: <stdin>:1:16: type check error: too many arguments
json: error: <stdin>:1:16: [null,null,null,null]
json: error: <stdin>:1:16:                ^
[null,null,null
command failed: json -d '{"type":"list","args":[{"type":"array","args":["null","null","null"]}]}' <<< '[null,null,null,null]'
$

--[ 28 ]------------------------------------------------------------------------

$ json -d '"type"' <<< '1'
1
$ json <<< ''
json: error: <stdin>:2:1: parse error: unexpected token
json: error: <stdin>:2:1: 
json: error: <stdin>:2:1: ^
command failed: json <<< ''
# [FIXED]
# the following failed assertion occur in the front-end on '\n' input
# when specifying a type in the command line:
# json: error: <stdin>:2:1: parse error: unexpected token
# json: fatal error: assertion failed: json-base.c:218:pos_error_verbose: x < e
$ json -d '"type"' <<< ''
json: error: <stdin>:2:1: parse error: unexpected token
json: error: <stdin>:2:1: 
json: error: <stdin>:2:1: ^
command failed: json -d '"type"' <<< ''
$

--[ 29 ]------------------------------------------------------------------------

$ json -O <<< '{"a":1;}' --no-verbose
json: error: <stdin>:1:7: lex error: invalid char
command failed: json -O <<< '{"a":1;}' --no-verbose
$ json -O <<< '{"a":1;}' -V
json: error: <stdin>:1:7: lex error: invalid char
json: error: <stdin>:1:7: {"a":1;}
json: error: <stdin>:1:7:       ^
command failed: json -O <<< '{"a":1;}' -V
$ json -Tc <<< '{"a":1;}' --no-verbose
json: error: <stdin>:1:7: parse error: invalid char
command failed: json -Tc <<< '{"a":1;}' --no-verbose
# [FIXED]
# the front end shouldn't fail to print out the error context
# $ json -Tc <<< '{"a":1;}' -V
# json: error: <stdin>:1:7: parse error: invalid char
# json: error: <stdin>: 'error-context-size' is too small for printing out input error context
$ json -Tc <<< '{"a":1;}' -V
json: error: <stdin>:1:7: parse error: invalid char
json: error: <stdin>:1:7: {"a":1;}
json: error: <stdin>:1:7:       ^
command failed: json -Tc <<< '{"a":1;}' -V
$

--[ 30 ]------------------------------------------------------------------------

# [FIXED]
# 'json' should indicate the error position at 1:3 not 1:4
$ echo -e '"\xf4\xbf"'|json -O -luV
json: error: <stdin>:1:3: lex error: invalid utf-8 encoding
json: error: <stdin>:1:3: "\xf4\xbf"
json: error: <stdin>:1:3:      ^
command failed: echo -e '"\xf4\xbf"'|json -O -luV
$

--[ 31 ]------------------------------------------------------------------------

# [FIXED]
# 'json' should indicate the error position at 1:3 not 1:5
$ echo -e '"\xf4\xbf\xbf"'|json -O -luV
json: error: <stdin>:1:3: lex error: invalid utf-8 encoding
json: error: <stdin>:1:3: "\xf4\xbf\xbf"
json: error: <stdin>:1:3:      ^
command failed: echo -e '"\xf4\xbf\xbf"'|json -O -luV
$

--[ 32 ]------------------------------------------------------------------------

# [FIXED]
# the following input is invalid UTF8 yet accepted by 'json'
$ echo -e '"\xf4\xbf\xbf\xbf"'|json -O -luV
json: error: <stdin>:1:3: lex error: invalid utf-8 encoding
json: error: <stdin>:1:3: "\xf4\xbf\xbf\xbf"
json: error: <stdin>:1:3:      ^
command failed: echo -e '"\xf4\xbf\xbf\xbf"'|json -O -luV
$

--[ 33 ]------------------------------------------------------------------------

# [FIXED]
# input cannot be accepted, since "\xe2" is invalid UTF8
$ echo -e '"\xe1\x80\x80""\xe2"'|json -luV -mO
json: error: <stdin>:1:8: lex error: invalid utf-8 encoding
json: error: <stdin>:1:8: "\xe1\x80\x80""\xe2"
json: error: <stdin>:1:8:                    ^
command failed: echo -e '"\xe1\x80\x80""\xe2"'|json -luV -mO
$

--[ 34 ]------------------------------------------------------------------------

# [FIXED]
# input cannot be accepted, since "\xe1\x80" is invalid UTF8
$ echo -e '"\xf1\x80\x80\x80""a\xe1\x80"'|json -luV -mO
json: error: <stdin>:1:11: lex error: invalid utf-8 encoding
json: error: <stdin>:1:11: "\xf1\x80\x80\x80""a\xe1\x80"
json: error: <stdin>:1:11:                             ^
command failed: echo -e '"\xf1\x80\x80\x80""a\xe1\x80"'|json -luV -mO
$

--[ 35 ]------------------------------------------------------------------------

# correct output
$ json -J <<< '{"a":{"x":"foo"}}'
/a/x=foo
# [FIXED]
# the expected output is "/a/x=foo"
$ json -J <<< '{"a":{"b":{},"x":"foo"}}'
/a/x=foo
# the expected output is "/a/x=foo"
$ json -J <<< '{"a":{"b":{"c":{}},"x":"foo"}}'
/a/x=foo
$

--[ 36 ]------------------------------------------------------------------------

# [FIXED]
# the following UTF-8 sequence is invalid, yet accepted by 'json'
$ echo -ne '"\xed\xa0\x80"'|json -luOV && echo OK
json: error: <stdin>:1:3: lex error: invalid utf-8 encoding
json: error: <stdin>:1:3: "\xed\xa0\x80"
json: error: <stdin>:1:3:      ^
command failed: echo -ne '"\xed\xa0\x80"'|json -luOV && echo OK
$

--[ 37 ]------------------------------------------------------------------------

# [FIXED]
# the error position below should have been 2:5, indicating the '+' char
$ json -V -Tc <<< $'{"type":"dict","args":[{"name":"a","type":"number"}],"expr":\n"a\\t+"}'
json: error: <stdin>:2:5: meta error: invalid dict expression: unexpected char
json: error: <stdin>:2:5: ","type":"number"}],"expr":\n"a\\t+"}
json: error: <stdin>:2:5:                                   ^
command failed: json -V -Tc <<< $'{"type":"dict","args":[{"name":"a","type":"number"}],"expr":\n"a\\t+"}'
$

--[ 38 ]------------------------------------------------------------------------

$ norm-err() { sed -r 's|json\.so: fatal error:|\n\0|'; }
$ dict-gen() { ../lib/test-gen --dict --depth=1 "$@"; }
$ json -t <(dict-gen -T -k64 -e '~`63`') -OV <<< '{}'
json: error: <stdin>:1:2: type check error: "dict" expression falsified: missing required args: "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61" and "62"
json: error: <stdin>:1:2: {}
json: error: <stdin>:1:2:  ^
command failed: json -t <(dict-gen -T -k64 -e '~`63`') -OV <<< '{}'
# [FIXED]
# the command below shouldn't produce any failed assertion
$ json -t <(dict-gen -T -k65 -e '~`64`') -OV <<< '{}' 2>&1|norm-err
json: error: <stdin>:1:2: type check error: "dict" expression falsified: missing required args: "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62" and "63"
json: error: <stdin>:1:2: {}
json: error: <stdin>:1:2:  ^
command failed: json -t <(dict-gen -T -k65 -e '~`64`') -OV <<< '{}' 2>&1|norm-err
$ dict-gen -V -k63|json -t <(dict-gen -T -k64 -e '~`63`') -OV && echo OK
OK
# [FIXED]
# the command below shouldn't fail, since the input provided to 'json'
# matches the type definition given; the root of this issue is -- similarly to
# the previous failed command above -- the macro BIT_SET_VAL_MASK_ in 'lib/bit-set.h':
$ set -o pipefail && dict-gen -V -k64|json -t <(dict-gen -T -k65 -e '~`64`') -OV && echo OK
OK
$

--[ 39 ]------------------------------------------------------------------------

$ json -VO -u <<< $'{"plain":"\xef\xbf\xc0"}'
json: error: <stdin>:1:13: lex error: invalid utf-8 encoding
json: error: <stdin>:1:13: {"plain":"\xef\xbf\xc0"}
json: error: <stdin>:1:13:                   ^
command failed: json -VO -u <<< $'{"plain":"\xef\xbf\xc0"}'
# [FIXED]
# the byte sequence '\xef\xbf\xc0' is invalid UTF8 and was correctly
# rejected by the command above; the following command should also reject it:
$ json -VT -u <<< $'{"plain":"\xef\xbf\xc0"}' && echo OK
json: error: <stdin>:1:13: parse error: invalid utf-8 encoding
json: error: <stdin>:1:13: {"plain":"\xef\xbf\xc0"}
json: error: <stdin>:1:13:                   ^
command failed: json -VT -u <<< $'{"plain":"\xef\xbf\xc0"}' && echo OK
$

--[ 40 ]------------------------------------------------------------------------

$ echo -n|json -Vt <(echo '{"type":"object",}') --echo
json: error: /dev/fd/??:1:18: type lib error: parse error: unexpected token
command failed: echo -n|json -Vt <(echo '{"type":"object",}') --echo
$ echo -n|json -Vt <(echo -e '{"type":"object",\n}') --parse
json: error: /dev/fd/??:2:1: type lib error: parse error: unexpected token
command failed: echo -n|json -Vt <(echo -e '{"type":"object",\n}') --parse
$ echo -n|json -Vt <(echo -e '{"type":"object",\n}') --pretty
json: error: /dev/fd/??:2:1: type lib error: parse error: unexpected token
command failed: echo -n|json -Vt <(echo -e '{"type":"object",\n}') --pretty
$ echo -n|json -Vt <(echo -e '{"type":"object",\n}') --terse
json: error: /dev/fd/??:2:1: type lib error: parse error: unexpected token
command failed: echo -n|json -Vt <(echo -e '{"type":"object",\n}') --terse
# [FIXED]
# the assertion below shouldn't have failed!
# $ echo -n|json -Vt <(echo -e '{"type":"object",\n}') --echo
# json: error: /dev/fd/??:2:1: type lib error: parse error: unexpected token
# json: fatal error: assertion failed: json-base.c:492:text_address_get_offset: false
$ echo -n|json -Vt <(echo -e '{"type":"object",\n}') --echo
json: error: /dev/fd/??:2:1: type lib error: parse error: unexpected token
command failed: echo -n|json -Vt <(echo -e '{"type":"object",\n}') --echo
$

--[ 41 ]------------------------------------------------------------------------

# [FIXED]
# the expected error position is 1:70
$ json -V -Tc <<< '{"type":"dict","args":[{"name":"\tfoo","type":"null"}],"expr":"`\tfoo"}'
json: error: <stdin>:1:70: meta error: invalid dict expression: unexpected end of expression
json: error: <stdin>:1:70: ","type":"null"}],"expr":"`\\tfoo"}
json: error: <stdin>:1:70:                                  ^
command failed: json -V -Tc <<< '{"type":"dict","args":[{"name":"\tfoo","type":"null"}],"expr":"`\tfoo"}'
# the expected error position is 1:74
$ json -V -Tc <<< '{"type":"dict","args":[{"name":"\t\tfoo","type":"null"}],"expr":"`\t\tfoo"}'
json: error: <stdin>:1:74: meta error: invalid dict expression: unexpected end of expression
json: error: <stdin>:1:74: "type":"null"}],"expr":"`\\t\\tfoo"}
json: error: <stdin>:1:74:                                   ^
command failed: json -V -Tc <<< '{"type":"dict","args":[{"name":"\t\tfoo","type":"null"}],"expr":"`\t\tfoo"}'
# the expected error position is 1:78
$ json -V -Tc <<< '{"type":"dict","args":[{"name":"\t\t\tfoo","type":"null"}],"expr":"`\t\t\tfoo"}'
json: error: <stdin>:1:78: meta error: invalid dict expression: unexpected end of expression
json: error: <stdin>:1:78: ype":"null"}],"expr":"`\\t\\t\\tfoo"}
json: error: <stdin>:1:78:                                    ^
command failed: json -V -Tc <<< '{"type":"dict","args":[{"name":"\t\t\tfoo","type":"null"}],"expr":"`\t\t\tfoo"}'
$

--[ 42 ]------------------------------------------------------------------------

# [FIXED]
# as per RFC7159, Section 7, strings must allow plain ASCII DEL chars
$ echo -e '"\x7f"'|json -VOl
$

--[ 43 ]------------------------------------------------------------------------

$ json -F -- json-litex.so -D <<< '{"abc":"0","xyz":"1"}' >/dev/null && echo OK
OK
# [FIXED]
# the command below shouldn't produce any failed assertion
$ json -F -- json-litex.so -D -q strcmp <<< '{"abc":"0","xyz":"1"}' >/dev/null && echo OK
OK
$

--[ 44 ]------------------------------------------------------------------------

$ json() { local n=''; [ "$1" == '--null' ] && { n=' >/dev/null'; shift; }; eval "set -o pipefail && LD_LIBRARY_PATH=../lib ../src/json --verbose $@$n"; }
$ echo -e 't\xc2\xa0'|json -S -uV
t\u00a0\n
$ echo -e 't\xc2'|json --null -S -uV
json: error: <stdin>:1:3: invalid utf-8 encoding
json: error: <stdin>:1:3: t\xc2
json: error: <stdin>:1:3:      ^
command failed: echo -e 't\xc2'|json --null -S -uV
$ echo -e 't\xa0'|json --null -S -uV
json: error: <stdin>:1:2: invalid utf-8 encoding
json: error: <stdin>:1:2: t\xa0
json: error: <stdin>:1:2:  ^
command failed: echo -e 't\xa0'|json --null -S -uV
$ echo -e '\t\xc2\xa0'|json -S -uV
\t\u00a0\n
$ echo -e '\t\xc2'|json --null -S -uV
json: error: <stdin>:1:3: invalid utf-8 encoding
json: error: <stdin>:1:3: \t\xc2
json: error: <stdin>:1:3:       ^
command failed: echo -e '\t\xc2'|json --null -S -uV
$ echo -e '\t\xa0'|json --null -S -uV
json: error: <stdin>:1:2: invalid utf-8 encoding
json: error: <stdin>:1:2: \t\xa0
json: error: <stdin>:1:2:   ^
command failed: echo -e '\t\xa0'|json --null -S -uV
$ echo -e '\xe2\x80\xa0\xc3\xa0'|json -S -uV
\u2020\u00e0\n
$ echo -e '\xe2\x80\xa0\xc3'|json --null -S -uV
json: error: <stdin>:1:5: invalid utf-8 encoding
json: error: <stdin>:1:5: \xe2\x80\xa0\xc3
json: error: <stdin>:1:5:                 ^
command failed: echo -e '\xe2\x80\xa0\xc3'|json --null -S -uV
$ echo -e '\xe2\x80\xa0\xa0'|json --null -S -uV
json: error: <stdin>:1:4: invalid utf-8 encoding
json: error: <stdin>:1:4: \xe2\x80\xa0\xa0
json: error: <stdin>:1:4:             ^
command failed: echo -e '\xe2\x80\xa0\xa0'|json --null -S -uV
$ echo -e '\xf0\x90\x80\x80\xc3\xa0'|json -S -uV
json: error: <stdin>:1:1: non-BMP utf-8 encoding
json: error: <stdin>:1:1: \xf0\x90\x80\x80\xc3\xa0
json: error: <stdin>:1:1: ^
command failed: echo -e '\xf0\x90\x80\x80\xc3\xa0'|json -S -uV
$ echo -e '\xf0\x90\x80\x80\xc3\xa0'|json -S -uV -s
\ud800\udc00\u00e0\n
$ echo -e '\xf0\x90\x80\x80\xc3'|json --null -S -uV -s
json: error: <stdin>:1:6: invalid utf-8 encoding
json: error: <stdin>:1:6: \xf0\x90\x80\x80\xc3
json: error: <stdin>:1:6:                     ^
command failed: echo -e '\xf0\x90\x80\x80\xc3'|json --null -S -uV -s
$ echo -e '\xf0\x90\x80\x80\xa0'|json --null -S -uV -s
json: error: <stdin>:1:5: invalid utf-8 encoding
json: error: <stdin>:1:5: \xf0\x90\x80\x80\xa0
json: error: <stdin>:1:5:                 ^
command failed: echo -e '\xf0\x90\x80\x80\xa0'|json --null -S -uV -s
$ echo -e '"t\xc2\xa0"'|json -O -luV && echo OK
OK
$ echo -e '"t\xc2"'|json -O -luV
json: error: <stdin>:1:4: lex error: invalid utf-8 encoding
json: error: <stdin>:1:4: "t\xc2"
json: error: <stdin>:1:4:       ^
command failed: echo -e '"t\xc2"'|json -O -luV
$ echo -e '"t\xa0"'|json -O -luV
json: error: <stdin>:1:3: lex error: invalid utf-8 encoding
json: error: <stdin>:1:3: "t\xa0"
json: error: <stdin>:1:3:   ^
command failed: echo -e '"t\xa0"'|json -O -luV
$ echo -e '"\\t\xc2\xa0"'|json -O -luV && echo OK
OK
# [FIXED]
# 'json' should indicate the error position at 1:5 not 1:4
$ echo -e '"\\t\xc2"'|json -O -luV
json: error: <stdin>:1:5: lex error: invalid utf-8 encoding
json: error: <stdin>:1:5: "\\t\xc2"
json: error: <stdin>:1:5:         ^
command failed: echo -e '"\\t\xc2"'|json -O -luV
# [FIXED]
# 'json' should indicate the error position at 1:4 not 1:3
$ echo -e '"\\t\xa0"'|json -O -luV
json: error: <stdin>:1:4: lex error: invalid utf-8 encoding
json: error: <stdin>:1:4: "\\t\xa0"
json: error: <stdin>:1:4:     ^
command failed: echo -e '"\\t\xa0"'|json -O -luV
$ echo -e '"\\u2020\xc3\xa0"'|json -O -luV && echo OK
OK
# [FIXED]
# 'json' should indicate the error position at 1:9 not 1:4
$ echo -e '"\\u2020\xc3"'|json -O -luV
json: error: <stdin>:1:9: lex error: invalid utf-8 encoding
json: error: <stdin>:1:9: "\\u2020\xc3"
json: error: <stdin>:1:9:             ^
command failed: echo -e '"\\u2020\xc3"'|json -O -luV
# [FIXED]
# 'json' should indicate the error position at 1:8 not 1:3
$ echo -e '"\\u2020\xa0"'|json -O -luV
json: error: <stdin>:1:8: lex error: invalid utf-8 encoding
json: error: <stdin>:1:8: "\\u2020\xa0"
json: error: <stdin>:1:8:         ^
command failed: echo -e '"\\u2020\xa0"'|json -O -luV
$ echo -e '"\\ud800\\udc00\xc3\xa0"'|json -O -luV -s && echo OK
OK
# [FIXED]
# 'json' should indicate the error position at 1:15 not 1:7
$ echo -e '"\\ud800\\udc00\xc3"'|json -O -luV -s
json: error: <stdin>:1:15: lex error: invalid utf-8 encoding
json: error: <stdin>:1:15: "\\ud800\\udc00\xc3"
json: error: <stdin>:1:15:                    ^
command failed: echo -e '"\\ud800\\udc00\xc3"'|json -O -luV -s
# [FIXED]
# 'json' should indicate the error position at 1:14 not 1:6
$ echo -e '"\\ud800\\udc00\xa0"'|json -O -luV -s
json: error: <stdin>:1:14: lex error: invalid utf-8 encoding
json: error: <stdin>:1:14: "\\ud800\\udc00\xa0"
json: error: <stdin>:1:14:                ^
command failed: echo -e '"\\ud800\\udc00\xa0"'|json -O -luV -s
$

--[ 45 ]------------------------------------------------------------------------

$ json -VO -d '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":{"type":"object","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":[]}}]}]}' <<< '{"foo":{}}' && echo OK
OK
$ json -VO -d '{"type":"object","args":[{"name":"foo","type":{"type":"list","args":[{"type":"object","args":[{"name":"bar","type":{"type":"object","args":[]}}]},{"type":"object","args":[{"name":"bar","type":{"type":"array","args":[]}}]}]}}]}' <<< '{"foo":{"bar":{}}}' && echo OK
OK
$ json -VO -d '{"type":"list","args":[{"type":"array","args":{"type":"object","args":[]}},{"type":"array","args":{"type":"array","args":[]}}]}' <<< '[{}]' && echo OK
OK
$ json -VO -d '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":[]}}]}]}' <<< '{"foo":[]}' && echo OK
OK
$ json -VO -d '{"type":"object","args":[{"name":"foo","type":{"type":"list","args":[{"type":"object","args":[{"name":"bar","type":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":"bar","type":{"type":"array","args":[]}}]}]}}]}' <<< '{"foo":{"bar":[]}}' && echo OK
OK
$ json -VO -d '{"type":"list","args":[{"type":"array","args":{"type":"dict","args":[]}},{"type":"array","args":{"type":"array","args":[]}}]}' <<< '[[]]' && echo OK
OK
# [FIXED]
# the commands below shouldn't produce any type check error
$ json -VO -d '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":[]}}]}]}' <<< '{"foo":{}}' && echo OK
OK
$ json -VO -d '{"type":"object","args":[{"name":"foo","type":{"type":"list","args":[{"type":"object","args":[{"name":"bar","type":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":"bar","type":{"type":"array","args":[]}}]}]}}]}' <<< '{"foo":{"bar":{}}}' && echo OK
OK
$ json -VO -d '{"type":"list","args":[{"type":"array","args":{"type":"dict","args":[]}},{"type":"array","args":{"type":"array","args":[]}}]}' <<< '[{}]' && echo OK
OK
$

--[ 46 ]------------------------------------------------------------------------

$ json -Tc <<< '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"array","args":[]}}]}]}' && echo OK
OK
$ json -Tc <<< '{"type":"object","args":[{"name":"foo","type":{"type":"list","args":[{"type":"object","args":[{"name":"bar","type":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":"bar","type":{"type":"array","args":[]}}]}]}}]}' && echo OK
OK
$ json -Tc <<< '{"type":"list","args":[{"type":"array","args":{"type":"dict","args":[]}},{"type":"array","args":{"type":"array","args":[]}}]}' && echo OK
OK
$ json -Tc -V <<< '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"dict","args":[]}}]}]}'
json: error: <stdin>:1:99: attribute error: invalid "list" type object: duplicated 'object' entry (previous defined at 1:24)
json: error: <stdin>:1:99: e":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":
json: error: <stdin>:1:99:                                 ^
command failed: json -Tc -V <<< '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"dict","args":[]}}]}]}'
$ json -Tc -V <<< '{"type":"list","args":[{"type":"array","args":{"type":"dict","args":[]}},{"type":"array","args":{"type":"dict","args":[]}}]}'
json: error: <stdin>:1:74: attribute error: invalid "list" type object: duplicated 'open array' entry (previous defined at 1:24)
json: error: <stdin>:1:74: rgs":{"type":"dict","args":[]}},{"type":"array","args":{"type":"d
json: error: <stdin>:1:74:                                 ^
command failed: json -Tc -V <<< '{"type":"list","args":[{"type":"array","args":{"type":"dict","args":[]}},{"type":"array","args":{"type":"dict","args":[]}}]}'
$ json -Tc -V <<< '{"type":"list","args":[{"type":"array","args":[{"type":"dict","args":[]}]},{"type":"array","args":[{"type":"dict","args":[]}]}]}'
json: error: <stdin>:1:76: attribute error: invalid "list" type object: duplicated 'closed array' entry (previous defined at 1:24)
json: error: <stdin>:1:76: s":[{"type":"dict","args":[]}]},{"type":"array","args":[{"type":"
json: error: <stdin>:1:76:                                 ^
command failed: json -Tc -V <<< '{"type":"list","args":[{"type":"array","args":[{"type":"dict","args":[]}]},{"type":"array","args":[{"type":"dict","args":[]}]}]}'
# [FIXED]
# the type defs below should have been rejected
$ json -Tc -V <<< '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"object","args":[]}}]}]}' && echo OK
json: error: <stdin>:1:70: attribute error: invalid "list" type object: object argument ambiguity (the other is at 1:145)
json: error: <stdin>:1:70: t","args":[{"name":"foo","type":{"type":"dict","args":[]}}]},{"ty
json: error: <stdin>:1:70:                                 ^
command failed: json -Tc -V <<< '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"object","args":[]}}]}]}' && echo OK
$ json -Tc -V <<< '{"type":"object","args":[{"name":"foo","type":{"type":"list","args":[{"type":"object","args":[{"name":"bar","type":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":"bar","type":{"type":"object","args":[]}}]}]}}]}' && echo OK
json: error: <stdin>:1:116: attribute error: invalid "list" type object: object argument ambiguity (the other is at 1:191)
json: error: <stdin>:1:116: t","args":[{"name":"bar","type":{"type":"dict","args":[]}}]},{"ty
json: error: <stdin>:1:116:                                 ^
command failed: json -Tc -V <<< '{"type":"object","args":[{"name":"foo","type":{"type":"list","args":[{"type":"object","args":[{"name":"bar","type":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":"bar","type":{"type":"object","args":[]}}]}]}}]}' && echo OK
$ json -Tc -V <<< '{"type":"list","args":[{"type":"array","args":{"type":"dict","args":[]}},{"type":"array","args":{"type":"object","args":[]}}]}' && echo OK
json: error: <stdin>:1:47: attribute error: invalid "list" type object: array argument ambiguity (the other is at 1:97)
json: error: <stdin>:1:47: ,"args":[{"type":"array","args":{"type":"dict","args":[]}},{"type
json: error: <stdin>:1:47:                                 ^
command failed: json -Tc -V <<< '{"type":"list","args":[{"type":"array","args":{"type":"dict","args":[]}},{"type":"array","args":{"type":"object","args":[]}}]}' && echo OK
$ json -Tc -V <<< '{"type":"list","args":[{"type":"array","args":{"type":"dict","args":[]}},{"type":"array","args":["object"]}]}' && echo OK 
json: error: <stdin>:1:47: attribute error: invalid "list" type object: array ambiguity (the other defined at 1:74)
json: error: <stdin>:1:47: ,"args":[{"type":"array","args":{"type":"dict","args":[]}},{"type
json: error: <stdin>:1:47:                                 ^
command failed: json -Tc -V <<< '{"type":"list","args":[{"type":"array","args":{"type":"dict","args":[]}},{"type":"array","args":["object"]}]}' && echo OK
$ json -Tc -V <<< '{"type":"list","args":[{"type":"array","args":{"type":"dict","args":[]}},{"type":"array","args":"object"}]}' && echo OK 
json: error: <stdin>:1:47: attribute error: invalid "list" type object: array argument ambiguity (the other is at 1:97)
json: error: <stdin>:1:47: ,"args":[{"type":"array","args":{"type":"dict","args":[]}},{"type
json: error: <stdin>:1:47:                                 ^
command failed: json -Tc -V <<< '{"type":"list","args":[{"type":"array","args":{"type":"dict","args":[]}},{"type":"array","args":"object"}]}' && echo OK
# [FIXED]
# the type defs below should have been rejected too
$ json -Tc -V <<< '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"dict","args":[{"name":"bar","type":"type"}]}}]}]}' && echo OK
json: error: <stdin>:1:145: attribute error: invalid "list" type object: object argument ambiguity (the other is at 1:70)
json: error: <stdin>:1:145: t","args":[{"name":"foo","type":{"type":"dict","args":[{"name":"b
json: error: <stdin>:1:145:                                 ^
command failed: json -Tc -V <<< '{"type":"list","args":[{"type":"object","args":[{"name":"foo","type":{"type":"dict","args":[]}}]},{"type":"object","args":[{"name":"foo","type":{"type":"dict","args":[{"name":"bar","type":"type"}]}}]}]}' && echo OK
$ json -Tc -V <<< '{"type":"list","args":[{"type":"array","args":{"type":"dict","args":[]}},{"type":"array","args":{"type":"dict","args":[{"name":"bar","type":"type"}]}}]}' && echo OK
json: error: <stdin>:1:97: attribute error: invalid "list" type object: array argument ambiguity (the other is at 1:47)
json: error: <stdin>:1:97: gs":[]}},{"type":"array","args":{"type":"dict","args":[{"name":"b
json: error: <stdin>:1:97:                                 ^
command failed: json -Tc -V <<< '{"type":"list","args":[{"type":"array","args":{"type":"dict","args":[]}},{"type":"array","args":{"type":"dict","args":[{"name":"bar","type":"type"}]}}]}' && echo OK
$ json -Tc -V <<< '{"type":"list","args":[{"type":"array","args":[{"type":"dict","args":[]}]},{"type":"array","args":[{"type":"dict","args":[{"name":"bar","type":"type"}]}]}]}' && echo OK
json: error: <stdin>:1:100: attribute error: invalid "list" type object: array argument ambiguity (the other is at 1:48)
json: error: <stdin>:1:100: ":[]}]},{"type":"array","args":[{"type":"dict","args":[{"name":"b
json: error: <stdin>:1:100:                                 ^
command failed: json -Tc -V <<< '{"type":"list","args":[{"type":"array","args":[{"type":"dict","args":[]}]},{"type":"array","args":[{"type":"dict","args":[{"name":"bar","type":"type"}]}]}]}' && echo OK
$

--[ 47 ]------------------------------------------------------------------------

$ norm() { sed -r '\|^//\|^\s*$|d' ${1:+"$1"}; }
# [FIXED]
# this output shows a bug within 'lib/json-litex.c': the structures
# 'json_litex_expr_node_t' '__0' and 'json_litex_expr_def_t' '__1' were
# generated twice in the output of 'json-litex.so' invoked with `-D' on
# a 'sobj' path library file
$ diff -u1000 -Lold <(norm libs/test-expr-dup/test-expr-dup.def) -Lnew <(json -F -- json-litex.so -p libs/test-expr-dup/test-expr-dup.so -D|norm)
$


