Sequence parser: wait for RS on startup (fix #687)

Per-RFC7464.
This commit is contained in:
Nicolas Williams committed 2015-06-17 11:24:34 -05:00
1 parent 0f5345e515
commit 4ef04e5b5c
2 files changed
+37 -27

No files matched your search

+34 -22
View File
@@ -77,7 +77,10 @@ static void parser_init(struct jv_parser* p, int flags) {
p->next = jv_invalid(); p->next = jv_invalid();
p->tokenbuf = 0; p->tokenbuf = 0;
p->tokenlen = p->tokenpos = 0; p->tokenlen = p->tokenpos = 0;
p->st = JV_PARSER_NORMAL; if ((p->flags & JV_PARSE_SEQ))
p->st = JV_PARSER_WAITING_FOR_RS;
else
p->st = JV_PARSER_NORMAL;
p->eof = 0; p->eof = 0;
p->curr_buf = 0; p->curr_buf = 0;
p->curr_buf_length = p->curr_buf_pos = p->curr_buf_is_partial = 0; p->curr_buf_length = p->curr_buf_pos = p->curr_buf_is_partial = 0;
@@ -720,8 +723,17 @@ jv jv_parser_next(struct jv_parser* p) {
presult msg = 0; presult msg = 0;
while (!msg && p->curr_buf_pos < p->curr_buf_length) { while (!msg && p->curr_buf_pos < p->curr_buf_length) {
ch = p->curr_buf[p->curr_buf_pos++]; ch = p->curr_buf[p->curr_buf_pos++];
if (ch != '\036' && p->st == JV_PARSER_WAITING_FOR_RS) if (p->st == JV_PARSER_WAITING_FOR_RS) {
if (ch == '\n') {
p->line++;
p->column = 0;
} else {
p->column++;
}
if (ch == '\036')
p->st = JV_PARSER_NORMAL;
continue; // need to resync, wait for RS continue; // need to resync, wait for RS
}
msg = scan(p, ch, &value); msg = scan(p, ch, &value);
} }
if (msg == OK) { if (msg == OK) {
@@ -752,26 +764,26 @@ jv jv_parser_next(struct jv_parser* p) {
p->eof = 1; p->eof = 1;
assert(p->curr_buf_pos == p->curr_buf_length); assert(p->curr_buf_pos == p->curr_buf_length);
jv_free(value); jv_free(value);
if (p->st != JV_PARSER_WAITING_FOR_RS) { if (p->st == JV_PARSER_WAITING_FOR_RS)
if (p->st != JV_PARSER_NORMAL) { return make_error(p, "Unfinished abandoned text at EOF at line %d, column %d", p->line, p->column);
value = make_error(p, "Unfinished string at EOF at line %d, column %d", p->line, p->column); if (p->st != JV_PARSER_NORMAL) {
parser_reset(p); value = make_error(p, "Unfinished string at EOF at line %d, column %d", p->line, p->column);
p->st = JV_PARSER_WAITING_FOR_RS; parser_reset(p);
return value; p->st = JV_PARSER_WAITING_FOR_RS;
} return value;
if ((msg = check_literal(p))) { }
value = make_error(p, "%s at EOF at line %d, column %d", msg, p->line, p->column); if ((msg = check_literal(p))) {
parser_reset(p); value = make_error(p, "%s at EOF at line %d, column %d", msg, p->line, p->column);
p->st = JV_PARSER_WAITING_FOR_RS; parser_reset(p);
return value; p->st = JV_PARSER_WAITING_FOR_RS;
} return value;
if (((p->flags & JV_PARSE_STREAMING) && p->stacklen != 0) || }
(!(p->flags & JV_PARSE_STREAMING) && p->stackpos != 0)) { if (((p->flags & JV_PARSE_STREAMING) && p->stacklen != 0) ||
value = make_error(p, "Unfinished JSON term at EOF at line %d, column %d", p->line, p->column); (!(p->flags & JV_PARSE_STREAMING) && p->stackpos != 0)) {
parser_reset(p); value = make_error(p, "Unfinished JSON term at EOF at line %d, column %d", p->line, p->column);
p->st = JV_PARSER_WAITING_FOR_RS; parser_reset(p);
return value; p->st = JV_PARSER_WAITING_FOR_RS;
} return value;
} }
// p->next is either invalid (nothing here, but no syntax error) // p->next is either invalid (nothing here, but no syntax error)
// or valid (this is the value). either way it's the thing to return // or valid (this is the value). either way it's the thing to return
+3 -5
View File
@@ -111,7 +111,6 @@ fi
## into tests/all.test ## into tests/all.test
cat > $d/expected <<EOF cat > $d/expected <<EOF
ignoring parse error: Potentially truncated top-level numeric value at line 1, column 2
ignoring parse error: Truncated value at line 2, column 5 ignoring parse error: Truncated value at line 2, column 5
ignoring parse error: Truncated value at line 2, column 25 ignoring parse error: Truncated value at line 2, column 25
ignoring parse error: Truncated value at line 2, column 41 ignoring parse error: Truncated value at line 2, column 41
@@ -120,7 +119,6 @@ printf '1\0362 3\n[0,1\036[4,5]true"ab"{"c":4\036{}{"d":5,"e":6"\036false\n'|$VA
cmp $d/out $d/expected cmp $d/out $d/expected
cat > $d/expected <<EOF cat > $d/expected <<EOF
ignoring parse error: Potentially truncated top-level numeric value at line 1, column 2
ignoring parse error: Truncated value at line 2, column 5 ignoring parse error: Truncated value at line 2, column 5
ignoring parse error: Truncated value at line 2, column 25 ignoring parse error: Truncated value at line 2, column 25
ignoring parse error: Truncated value at line 3, column 1 ignoring parse error: Truncated value at line 3, column 1
@@ -131,21 +129,21 @@ cmp $d/out $d/expected
# Note that here jq sees no inputs at all but it still succeeds because # Note that here jq sees no inputs at all but it still succeeds because
# --seq ignores parse errors # --seq ignores parse errors
cat > $d/expected <<EOF cat > $d/expected <<EOF
ignoring parse error: Unfinished string at EOF at line 1, column 4 ignoring parse error: Unfinished abandoned text at EOF at line 1, column 4
EOF EOF
printf '"foo'|./jq -ce --seq . > $d/out 2>&1 printf '"foo'|./jq -ce --seq . > $d/out 2>&1
cmp $d/out $d/expected cmp $d/out $d/expected
# Numeric values truncated by EOF are ignored # Numeric values truncated by EOF are ignored
cat > $d/expected <<EOF cat > $d/expected <<EOF
ignoring parse error: Potentially truncated top-level numeric value at EOF at line 1, column 1 ignoring parse error: Unfinished abandoned text at EOF at line 1, column 1
EOF EOF
printf '1'|./jq -ce --seq . > $d/out 2>&1 printf '1'|./jq -ce --seq . > $d/out 2>&1
cmp $d/out $d/expected cmp $d/out $d/expected
cat > $d/expected <<EOF cat > $d/expected <<EOF
EOF EOF
printf '1\n'|./jq -ces --seq '. == [1]' >/dev/null 2> $d/out printf '1\n'|./jq -cen --seq '[inputs] == []' >/dev/null 2> $d/out
cmp $d/out $d/expected cmp $d/out $d/expected
## Test streaming parser ## Test streaming parser