Skip to content

Commit

Permalink
json: Correct position tracking in JSON parser implementations.
Browse files Browse the repository at this point in the history
When json_lex_input() returns false, the parser does not consume the byte
passed in.  That byte will get processed again in the next iteration of
the json_parser_feed() loop.  Therefore, until now, this code has
double-counted bytes that cause a false return from json_lex_input().

This fixes the problem.  Every input byte is now counted only once.

Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
blp committed Apr 26, 2012
1 parent 3a4548c commit c640c04
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 18 deletions.
15 changes: 7 additions & 8 deletions lib/json.c
Original file line number Diff line number Diff line change
Expand Up @@ -908,14 +908,6 @@ json_lex_input(struct json_parser *p, unsigned char c)
{
struct json_token token;

p->byte_number++;
if (c == '\n') {
p->column_number = 0;
p->line_number++;
} else {
p->column_number++;
}

switch (p->lex_state) {
case JSON_LEX_START:
switch (c) {
Expand Down Expand Up @@ -1092,6 +1084,13 @@ json_parser_feed(struct json_parser *p, const char *input, size_t n)
size_t i;
for (i = 0; !p->done && i < n; ) {
if (json_lex_input(p, input[i])) {
p->byte_number++;
if (input[i] == '\n') {
p->column_number = 0;
p->line_number++;
} else {
p->column_number++;
}
i++;
}
}
Expand Down
20 changes: 11 additions & 9 deletions python/ovs/json.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2010, 2011 Nicira Networks
# Copyright (c) 2010, 2011, 2012 Nicira Networks
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -420,13 +420,6 @@ def __lex_string(self, c):
return True

def __lex_input(self, c):
self.byte_number += 1
if c == '\n':
self.column_number = 0
self.line_number += 1
else:
self.column_number += 1

eat = self.lex_state(self, c)
assert eat is True or eat is False
return eat
Expand Down Expand Up @@ -557,7 +550,16 @@ def feed(self, s):
while True:
if self.done or i >= len(s):
return i
if self.__lex_input(s[i]):

c = s[i]
if self.__lex_input(c):
self.byte_number += 1
if c == '\n':
self.column_number = 0
self.line_number += 1
else:
self.column_number += 1

i += 1

def is_done(self):
Expand Down
2 changes: 1 addition & 1 deletion tests/ovsdb-log.at
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ AT_CHECK(
file: read: [0]
file: read: [1]
file: read: [2]
file: read failed: syntax error: file: 5 bytes starting at offset 228 are not valid JSON (line 1, column 0, byte 5: syntax error at beginning of input)
file: read failed: syntax error: file: 5 bytes starting at offset 228 are not valid JSON (line 0, column 4, byte 4: syntax error at beginning of input)
file: write:["replacement data"] successful
]], [ignore])
AT_CHECK(
Expand Down

0 comments on commit c640c04

Please sign in to comment.