From b23d2eb422eddaec0f2800a6b92f428c19f3a5f9 Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Mon, 23 Jan 2012 17:00:40 +0100 Subject: [PATCH] Drop eval-based json parser fallback Drop potentially-unsafe eval-based json parser that was used as a fallback in case simplejson and json were not available. Let's assume people run Python 2.6 or can install simplejson if they are not. Fixes bug 909568. Change-Id: I1b1860a77de5075fcea291a4f1b320a3e9e6261f --- bin/swift | 35 +++-------------------------- swift/common/client.py | 33 ++-------------------------- test/unit/common/test_client.py | 39 --------------------------------- 3 files changed, 5 insertions(+), 102 deletions(-) diff --git a/bin/swift b/bin/swift index 52b5486ec3..31ce80725a 100755 --- a/bin/swift +++ b/bin/swift @@ -71,38 +71,9 @@ try: from simplejson import loads as json_loads from simplejson import dumps as json_dumps except ImportError: - try: - # 2.6 will have a json module in the stdlib - from json import loads as json_loads - from json import dumps as json_dumps - except ImportError: - # fall back on local parser otherwise - comments = compile(r'/\*.*\*/|//[^\r\n]*', DOTALL) - - def json_loads(string): - ''' - Fairly competent json parser exploiting the python tokenizer and - eval(). -- From python-cloudfiles - - _loads(serialized_json) -> object - ''' - try: - res = [] - consts = {'true': True, 'false': False, 'null': None} - string = '(' + comments.sub('', string) + ')' - for type, val, _junk, _junk, _junk in \ - generate_tokens(StringIO(string).readline): - if (type == OP and val not in '[]{}:,()-') or \ - (type == NAME and val not in consts): - raise AttributeError() - elif type == STRING: - res.append('u') - res.append(val.replace('\\/', '/')) - else: - res.append(val) - return eval(''.join(res), {}, consts) - except Exception: - raise AttributeError() + # 2.6 will have a json module in the stdlib + from json import loads as json_loads + from json import dumps as json_dumps class ClientException(Exception): diff --git a/swift/common/client.py b/swift/common/client.py index a47a09b9fc..93269ad467 100644 --- a/swift/common/client.py +++ b/swift/common/client.py @@ -57,37 +57,8 @@ try: # simplejson is popular and pretty good from simplejson import loads as json_loads except ImportError: - try: - # 2.6 will have a json module in the stdlib - from json import loads as json_loads - except ImportError: - # fall back on local parser otherwise - comments = compile(r'/\*.*\*/|//[^\r\n]*', DOTALL) - - def json_loads(string): - ''' - Fairly competent json parser exploiting the python tokenizer and - eval(). -- From python-cloudfiles - - _loads(serialized_json) -> object - ''' - try: - res = [] - consts = {'true': True, 'false': False, 'null': None} - string = '(' + comments.sub('', string) + ')' - for type, val, _junk, _junk, _junk in \ - generate_tokens(StringIO(string).readline): - if (type == OP and val not in '[]{}:,()-') or \ - (type == NAME and val not in consts): - raise AttributeError() - elif type == STRING: - res.append('u') - res.append(val.replace('\\/', '/')) - else: - res.append(val) - return eval(''.join(res), {}, consts) - except Exception: - raise AttributeError() + # 2.6 will have a json module in the stdlib + from json import loads as json_loads class ClientException(Exception): diff --git a/test/unit/common/test_client.py b/test/unit/common/test_client.py index 29d1e5ff5d..f25ef4c7ad 100644 --- a/test/unit/common/test_client.py +++ b/test/unit/common/test_client.py @@ -109,45 +109,6 @@ class TestJsonImport(unittest.TestCase): else: self.assertEquals(loads, c.json_loads) - def test_no_json(self): - # first break simplejson - try: - import simplejson - except ImportError: - # not installed, so we don't have to break it for these tests - pass - else: - delattr(simplejson, 'loads') - - # then break json - try: - import json - except ImportError: - # not installed, so we don't have to break it for these tests - _orig_dumps = None - else: - # before we break json, grab a copy of the orig_dumps function - _orig_dumps = json.dumps - delattr(json, 'loads') - reload(c) - - if _orig_dumps: - # basic test of swift.common.client.json_loads using json.loads - data = { - 'string': 'value', - 'int': 0, - 'bool': True, - 'none': None, - } - json_string = _orig_dumps(data) - else: - # even more basic test using a hand encoded json string - data = ['value1', 'value2'] - json_string = "['value1', 'value2']" - - self.assertEquals(data, c.json_loads(json_string)) - self.assertRaises(AttributeError, c.json_loads, self) - class MockHttpTest(unittest.TestCase):