Refactor decoder input stream
- Add a new field position to the json_error_t structure. This is the position in bytes from the beginning of the input. - Keep track of line, column and input position in the stream level. Previously, only line was tracked, and it was in the lexer level, so this info was not available for UTF-8 decoding errors. - While at it, refactor tests so that no separate "stripped" tests are required. json_process is now able to strip whitespace from its input, and the "valid" and "invalid" test suites now use this to test both non-stripped and stripped input. Closes GH-9.
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <jansson.h>
|
||||
|
||||
static int getenv_int(const char *name)
|
||||
@@ -25,6 +27,26 @@ static int getenv_int(const char *name)
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
/* Return a pointer to the first non-whitespace character of str.
|
||||
Modifies str so that all trailing whitespace characters are
|
||||
replaced by '\0'. */
|
||||
static const char *strip(char *str)
|
||||
{
|
||||
size_t length;
|
||||
char *result = str;
|
||||
while(*result && isspace(*result))
|
||||
result++;
|
||||
|
||||
length = strlen(result);
|
||||
if(length == 0)
|
||||
return result;
|
||||
|
||||
while(isspace(result[length - 1]))
|
||||
result[--length] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int indent = 0;
|
||||
@@ -59,9 +81,39 @@ int main(int argc, char *argv[])
|
||||
if(getenv_int("JSON_SORT_KEYS"))
|
||||
flags |= JSON_SORT_KEYS;
|
||||
|
||||
json = json_loadf(stdin, 0, &error);
|
||||
if(getenv_int("STRIP")) {
|
||||
/* Load to memory, strip leading and trailing whitespace */
|
||||
size_t size = 0, used = 0;
|
||||
char *buffer = NULL;
|
||||
|
||||
while(1) {
|
||||
int count;
|
||||
|
||||
size = (size == 0 ? 128 : size * 2);
|
||||
buffer = realloc(buffer, size);
|
||||
if(!buffer) {
|
||||
fprintf(stderr, "Unable to allocate %d bytes\n", (int)size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
count = fread(buffer + used, 1, size - used, stdin);
|
||||
if(count < size - used) {
|
||||
buffer[used + count] = '\0';
|
||||
break;
|
||||
}
|
||||
used += count;
|
||||
}
|
||||
|
||||
json = json_loads(strip(buffer), 0, &error);
|
||||
free(buffer);
|
||||
}
|
||||
else
|
||||
json = json_loadf(stdin, 0, &error);
|
||||
|
||||
if(!json) {
|
||||
fprintf(stderr, "%d\n%s\n", error.line, error.text);
|
||||
fprintf(stderr, "%d %d %d\n%s\n",
|
||||
error.line, error.column, error.position,
|
||||
error.text);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ int main()
|
||||
/* NULL format */
|
||||
if(json_pack_ex(&error, 0, NULL))
|
||||
fail("json_pack failed to catch NULL format string");
|
||||
if(error.line != 1 || error.column != 1)
|
||||
if(error.line != -1 || error.column != -1)
|
||||
fail("json_pack didn't get the error coordinates right!");
|
||||
|
||||
/* More complicated checks for row/columns */
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
invalid token near '''
|
||||
@@ -1 +0,0 @@
|
||||
['
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
'[' or '{' expected near 'a'
|
||||
@@ -1 +0,0 @@
|
||||
aå
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
string or '}' expected near ','
|
||||
@@ -1 +0,0 @@
|
||||
{,
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
unexpected token near ','
|
||||
@@ -1 +0,0 @@
|
||||
[,
|
||||
@@ -1 +0,0 @@
|
||||
[1,
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
'[' or '{' expected near end of file
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
\u0000 is not allowed
|
||||
@@ -1 +0,0 @@
|
||||
["\u0000 (null byte not allowed)"]
|
||||
@@ -1 +0,0 @@
|
||||
[1,]
|
||||
@@ -1,2 +0,0 @@
|
||||
6
|
||||
unexpected token near ']'
|
||||
@@ -1,6 +0,0 @@
|
||||
[1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
]
|
||||
@@ -1,2 +0,0 @@
|
||||
2
|
||||
end of file expected near 'foo'
|
||||
@@ -1,2 +0,0 @@
|
||||
[1,2,3]
|
||||
foo
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
end of file expected near 'foo'
|
||||
@@ -1 +0,0 @@
|
||||
[1,2,3]foo
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
invalid token near '0'
|
||||
@@ -1 +0,0 @@
|
||||
[012]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
invalid escape near '"\'
|
||||
@@ -1 +0,0 @@
|
||||
["\a <-- invalid escape"]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
invalid token near 'troo'
|
||||
@@ -1 +0,0 @@
|
||||
[troo
|
||||
@@ -1 +0,0 @@
|
||||
[-123foo]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
']' expected near 'foo'
|
||||
@@ -1 +0,0 @@
|
||||
[-123.123foo]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
invalid Unicode '\uD888\u3210'
|
||||
@@ -1 +0,0 @@
|
||||
["\uD888\u3210 (first surrogate and invalid second surrogate)"]
|
||||
@@ -1 +0,0 @@
|
||||
{
|
||||
@@ -1 +0,0 @@
|
||||
[
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
invalid Unicode '\uDFAA'
|
||||
@@ -1 +0,0 @@
|
||||
["\uDFAA (second surrogate on it's own)"]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
invalid token near '-'
|
||||
@@ -1 +0,0 @@
|
||||
[-foo]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
invalid token near '-0'
|
||||
@@ -1 +0,0 @@
|
||||
[-012]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
control character 0x0 near '"null byte '
|
||||
Binary file not shown.
@@ -1,2 +0,0 @@
|
||||
1
|
||||
invalid token near end of file
|
||||
Binary file not shown.
@@ -1,2 +0,0 @@
|
||||
1
|
||||
'[' or '{' expected near 'null'
|
||||
@@ -1 +0,0 @@
|
||||
null
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
string or '}' expected near '''
|
||||
@@ -1 +0,0 @@
|
||||
{'a'
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
'}' expected near '123'
|
||||
@@ -1 +0,0 @@
|
||||
{"a":"a" 123}
|
||||
@@ -1 +0,0 @@
|
||||
[{}
|
||||
@@ -1 +0,0 @@
|
||||
{"a"
|
||||
@@ -1 +0,0 @@
|
||||
{"a":
|
||||
@@ -1 +0,0 @@
|
||||
{"a":"a
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
invalid token near '1e'
|
||||
@@ -1 +0,0 @@
|
||||
[1ea]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
real number overflow near '-123123e100000'
|
||||
@@ -1 +0,0 @@
|
||||
[-123123e100000]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
real number overflow near '123123e100000'
|
||||
@@ -1 +0,0 @@
|
||||
[123123e100000]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
invalid token near '1e'
|
||||
@@ -1 +0,0 @@
|
||||
[1e]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
invalid token near '1.'
|
||||
@@ -1 +0,0 @@
|
||||
[1.]
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009-2011 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
is_test() {
|
||||
test -d $test_path
|
||||
}
|
||||
|
||||
run_test() {
|
||||
$json_process <$test_path/input >$test_log/stdout 2>$test_log/stderr
|
||||
valgrind_check $test_log/stderr || return 1
|
||||
cmp -s $test_path/error $test_log/stderr
|
||||
}
|
||||
|
||||
show_error() {
|
||||
valgrind_show_error && return
|
||||
|
||||
echo "EXPECTED ERROR:"
|
||||
nl -bn $test_path/error
|
||||
echo "ACTUAL ERROR:"
|
||||
nl -bn $test_log/stderr
|
||||
}
|
||||
|
||||
. $top_srcdir/test/scripts/run-tests.sh
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
control character 0x9 near '"'
|
||||
@@ -1 +0,0 @@
|
||||
[" <-- tab character"]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
too big negative integer
|
||||
@@ -1 +0,0 @@
|
||||
[-123123123123123123123123123123]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
too big integer
|
||||
@@ -1 +0,0 @@
|
||||
[123123123123123123123123123123]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
invalid Unicode '\uDADA'
|
||||
@@ -1 +0,0 @@
|
||||
["\uDADA (first surrogate without the second)"]
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
'[' or '{' expected near 'å'
|
||||
@@ -1 +0,0 @@
|
||||
å
|
||||
@@ -1 +0,0 @@
|
||||
[{
|
||||
@@ -1 +0,0 @@
|
||||
["a"
|
||||
@@ -1 +0,0 @@
|
||||
{"
|
||||
@@ -1 +0,0 @@
|
||||
{"a
|
||||
@@ -1,2 +0,0 @@
|
||||
1
|
||||
string or '}' expected near '['
|
||||
@@ -1 +0,0 @@
|
||||
{[
|
||||
@@ -1 +0,0 @@
|
||||
["a
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xed at position 2
|
||||
1 2 2
|
||||
unable to decode byte 0xed near '"'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xe5 at position 3
|
||||
1 3 3
|
||||
unable to decode byte 0xe5 near '"\'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xe5 at position 1
|
||||
1 1 1
|
||||
unable to decode byte 0xe5
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xe5 at position 4
|
||||
1 4 4
|
||||
unable to decode byte 0xe5 near '123'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xe5 at position 4
|
||||
1 4 4
|
||||
unable to decode byte 0xe5 near '"\u'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xe5 at position 4
|
||||
1 4 4
|
||||
unable to decode byte 0xe5 near '1e1'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xe5 at position 2
|
||||
1 2 2
|
||||
unable to decode byte 0xe5 near 'a'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xe5 at position 2
|
||||
1 2 2
|
||||
unable to decode byte 0xe5 near '0'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xe5 at position 3
|
||||
1 3 3
|
||||
unable to decode byte 0xe5 near '1e'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xe5 at position 2
|
||||
1 2 2
|
||||
unable to decode byte 0xe5 near '"'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xe5 at position 0
|
||||
1 0 0
|
||||
unable to decode byte 0xe5
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0x81 at position 2
|
||||
1 2 2
|
||||
unable to decode byte 0x81 near '"'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xf4 at position 2
|
||||
1 2 2
|
||||
unable to decode byte 0xf4 near '"'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xe0 at position 2
|
||||
1 2 2
|
||||
unable to decode byte 0xe0 near '"'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xf0 at position 2
|
||||
1 2 2
|
||||
unable to decode byte 0xf0 near '"'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xc1 at position 2
|
||||
1 2 2
|
||||
unable to decode byte 0xc1 near '"'
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-1
|
||||
unable to decode byte 0xfd at position 2
|
||||
1 2 2
|
||||
unable to decode byte 0xfd near '"'
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user