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:
Petri Lehtinen
2011-02-22 10:47:02 +02:00
parent e54ea1f7c9
commit 5df7b79397
245 changed files with 379 additions and 465 deletions

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -1,2 +0,0 @@
1
invalid token near '''

View File

@@ -1 +0,0 @@
['

View File

@@ -1,2 +0,0 @@
1
'[' or '{' expected near 'a'

View File

@@ -1,2 +0,0 @@
1
string or '}' expected near ','

View File

@@ -1 +0,0 @@
{,

View File

@@ -1,2 +0,0 @@
1
unexpected token near ','

View File

@@ -1 +0,0 @@
[,

View File

@@ -1 +0,0 @@
[1,

View File

@@ -1,2 +0,0 @@
1
'[' or '{' expected near end of file

View File

@@ -1,2 +0,0 @@
1
\u0000 is not allowed

View File

@@ -1 +0,0 @@
["\u0000 (null byte not allowed)"]

View File

@@ -1,2 +0,0 @@
6
unexpected token near ']'

View File

@@ -1,6 +0,0 @@
[1,
2,
3,
4,
5,
]

View File

@@ -1,2 +0,0 @@
2
end of file expected near 'foo'

View File

@@ -1,2 +0,0 @@
[1,2,3]
foo

View File

@@ -1,2 +0,0 @@
1
end of file expected near 'foo'

View File

@@ -1 +0,0 @@
[1,2,3]foo

View File

@@ -1,2 +0,0 @@
1
invalid token near '0'

View File

@@ -1,2 +0,0 @@
1
invalid escape near '"\'

View File

@@ -1 +0,0 @@
["\a <-- invalid escape"]

View File

@@ -1,2 +0,0 @@
1
invalid token near 'troo'

View File

@@ -1 +0,0 @@
[troo

View File

@@ -1 +0,0 @@
[-123foo]

View File

@@ -1,2 +0,0 @@
1
']' expected near 'foo'

View File

@@ -1 +0,0 @@
[-123.123foo]

View File

@@ -1,2 +0,0 @@
1
invalid Unicode '\uD888\u3210'

View File

@@ -1 +0,0 @@
["\uD888\u3210 (first surrogate and invalid second surrogate)"]

View File

@@ -1,2 +0,0 @@
1
invalid Unicode '\uDFAA'

View File

@@ -1 +0,0 @@
["\uDFAA (second surrogate on it's own)"]

View File

@@ -1,2 +0,0 @@
1
invalid token near '-'

View File

@@ -1,2 +0,0 @@
1
invalid token near '-0'

View File

@@ -1,2 +0,0 @@
1
control character 0x0 near '"null byte '

View File

@@ -1,2 +0,0 @@
1
invalid token near end of file

View File

@@ -1,2 +0,0 @@
1
'[' or '{' expected near 'null'

View File

@@ -1 +0,0 @@
null

View File

@@ -1,2 +0,0 @@
1
string or '}' expected near '''

View File

@@ -1 +0,0 @@
{'a'

View File

@@ -1,2 +0,0 @@
1
'}' expected near '123'

View File

@@ -1 +0,0 @@
{"a":"a" 123}

View File

@@ -1 +0,0 @@
{"a"

View File

@@ -1 +0,0 @@
{"a":

View File

@@ -1,2 +0,0 @@
1
invalid token near '1e'

View File

@@ -1 +0,0 @@
[1ea]

View File

@@ -1,2 +0,0 @@
1
real number overflow near '-123123e100000'

View File

@@ -1 +0,0 @@
[-123123e100000]

View File

@@ -1,2 +0,0 @@
1
real number overflow near '123123e100000'

View File

@@ -1 +0,0 @@
[123123e100000]

View File

@@ -1,2 +0,0 @@
1
invalid token near '1e'

View File

@@ -1 +0,0 @@
[1e]

View File

@@ -1,2 +0,0 @@
1
invalid token near '1.'

View File

@@ -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

View File

@@ -1,2 +0,0 @@
1
control character 0x9 near '"'

View File

@@ -1 +0,0 @@
[" <-- tab character"]

View File

@@ -1,2 +0,0 @@
1
too big negative integer

View File

@@ -1 +0,0 @@
[-123123123123123123123123123123]

View File

@@ -1,2 +0,0 @@
1
too big integer

View File

@@ -1 +0,0 @@
[123123123123123123123123123123]

View File

@@ -1,2 +0,0 @@
1
invalid Unicode '\uDADA'

View File

@@ -1 +0,0 @@
["\uDADA (first surrogate without the second)"]

View File

@@ -1,2 +0,0 @@
1
'[' or '{' expected near 'å'

View File

@@ -1 +0,0 @@
["a"

View File

@@ -1 +0,0 @@
{"a

View File

@@ -1,2 +0,0 @@
1
string or '}' expected near '['

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xed at position 2
1 2 2
unable to decode byte 0xed near '"'

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xe5 at position 3
1 3 3
unable to decode byte 0xe5 near '"\'

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xe5 at position 1
1 1 1
unable to decode byte 0xe5

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xe5 at position 4
1 4 4
unable to decode byte 0xe5 near '123'

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xe5 at position 4
1 4 4
unable to decode byte 0xe5 near '"\u'

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xe5 at position 4
1 4 4
unable to decode byte 0xe5 near '1e1'

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xe5 at position 2
1 2 2
unable to decode byte 0xe5 near 'a'

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xe5 at position 2
1 2 2
unable to decode byte 0xe5 near '0'

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xe5 at position 3
1 3 3
unable to decode byte 0xe5 near '1e'

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xe5 at position 2
1 2 2
unable to decode byte 0xe5 near '"'

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xe5 at position 0
1 0 0
unable to decode byte 0xe5

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0x81 at position 2
1 2 2
unable to decode byte 0x81 near '"'

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xf4 at position 2
1 2 2
unable to decode byte 0xf4 near '"'

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xe0 at position 2
1 2 2
unable to decode byte 0xe0 near '"'

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xf0 at position 2
1 2 2
unable to decode byte 0xf0 near '"'

View File

@@ -1,2 +1,2 @@
-1
unable to decode byte 0xc1 at position 2
1 2 2
unable to decode byte 0xc1 near '"'

View File

@@ -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