[ovs-dev] [PATCH] json: Correct position tracking in JSON parser.

Ben Pfaff blp at nicira.com
Wed Apr 25 22:38:59 UTC 2012


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 <blp at nicira.com>
---
 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 37bdece..d514a90 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 417d231..fa5fd15 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 bd06110..055dc70 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(
-- 
1.7.2.5




More information about the dev mailing list