Skip to content

Commit

Permalink
Un-revert Work around Python/C JSON unicode differences
Browse files Browse the repository at this point in the history
This fix was reverted because it depended on a small bit of code
in a patch that was reverted that changed some python/ovs testing
and build. The fix is still necessary.

The OVS C-based JSON parser operates on bytes, so the parser_feed
function returns the number of bytes that are processed. The pure
Python JSON parser currently operates on unicode, so it expects
that Parser.feed() returns a number of characters. This difference
leads to parsing errors when unicode characters are passed to the
C JSON parser from Python.

Acked-by: Lucas Alvares Gomes <[email protected]>
Signed-off-by: Terry Wilson <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
otherwiseguy authored and blp committed Jan 15, 2019
1 parent 96edaf5 commit 75ff711
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 6 deletions.
10 changes: 6 additions & 4 deletions python/ovs/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@

import six

PARSER_C = 'C'
PARSER_PY = 'PYTHON'
try:
import ovs._json
PARSER = PARSER_C
except ImportError:
pass
PARSER = PARSER_PY

__pychecker__ = 'no-stringiter'

Expand Down Expand Up @@ -91,10 +94,9 @@ class Parser(object):
MAX_HEIGHT = 1000

def __new__(cls, *args, **kwargs):
try:
if PARSER == PARSER_C:
return ovs._json.Parser(*args, **kwargs)
except NameError:
return super(Parser, cls).__new__(cls)
return super(Parser, cls).__new__(cls)

def __init__(self, check_trailer=False):
self.check_trailer = check_trailer
Expand Down
9 changes: 7 additions & 2 deletions python/ovs/jsonrpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@ def recv(self):
# data, so we convert it here as soon as possible.
if data and not error:
try:
data = decoder.decode(data)
if six.PY3 or ovs.json.PARSER == ovs.json.PARSER_PY:
data = decoder.decode(data)
except UnicodeError:
error = errno.EILSEQ
if error:
Expand All @@ -298,7 +299,11 @@ def recv(self):
else:
if self.parser is None:
self.parser = ovs.json.Parser()
self.input = self.input[self.parser.feed(self.input):]
if six.PY3 and ovs.json.PARSER == ovs.json.PARSER_C:
self.input = self.input.encode('utf-8')[
self.parser.feed(self.input):].decode()
else:
self.input = self.input[self.parser.feed(self.input):]
if self.parser.is_done():
msg = self.__process_msg()
if msg:
Expand Down

0 comments on commit 75ff711

Please sign in to comment.