From c640c04f643f9cd9c9b88a9989590e8a02954f7f Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 26 Apr 2012 09:48:28 -0700 Subject: [PATCH] json: Correct position tracking in JSON parser implementations. 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 --- lib/json.c | 15 +++++++-------- python/ovs/json.py | 20 +++++++++++--------- tests/ovsdb-log.at | 2 +- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/lib/json.c b/lib/json.c index 37bdece5..d514a90d 100644 --- a/lib/json.c +++ b/lib/json.c @@ -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) { @@ -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++; } } diff --git a/python/ovs/json.py b/python/ovs/json.py index 417d2316..fa5fd154 100644 --- a/python/ovs/json.py +++ b/python/ovs/json.py @@ -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. @@ -420,13 +420,6 @@ class Parser(object): 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 @@ -557,7 +550,16 @@ class Parser(object): 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): diff --git a/tests/ovsdb-log.at b/tests/ovsdb-log.at index bd061105..055dc70c 100644 --- a/tests/ovsdb-log.at +++ b/tests/ovsdb-log.at @@ -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( -- 2.30.2