Fix obj versioning w/non-ASCII container name

If you create a container with a non-ASCII name, and then make another
container with X-Versions-Location: first-cøntåîner, *and* you're
serializing stuff in memcache as json (the default), when the proxy
tries to make a versioned object, it will crash.

The fix is to make sure that get_container_info() always returns strs,
not unicodes.

The long-term fix would be to get rid of simplejson entirely, as its
decoder can't make up its mind whether JSON strings should be Python
strs or unicodes, and that makes it really really easy to write bugs
like this.

Change-Id: Ib20ea5fb884484a4246d7a21a9f1e2ffd82eb04f
This commit is contained in:
Samuel Merritt
2013-12-18 10:38:34 -08:00
parent 3c82cfc7a9
commit ace2aa33b1
2 changed files with 7 additions and 1 deletions

View File

@@ -420,6 +420,9 @@ def _get_info_cache(app, env, account, container=None):
if memcache:
info = memcache.get(cache_key)
if info:
for key in info:
if isinstance(info[key], unicode):
info[key] = info[key].encode("utf-8")
env[env_key] = info
return info
return None

View File

@@ -251,7 +251,9 @@ class TestFuncs(unittest.TestCase):
def test_get_container_info_cache(self):
cached = {'status': 404,
'bytes': 3333,
'object_count': 10}
'object_count': 10,
# simplejson sometimes hands back strings, sometimes unicodes
'versions': u"\u1F4A9"}
req = Request.blank("/v1/account/cont",
environ={'swift.cache': FakeCache(cached)})
with patch('swift.proxy.controllers.base.'
@@ -260,6 +262,7 @@ class TestFuncs(unittest.TestCase):
self.assertEquals(resp['bytes'], 3333)
self.assertEquals(resp['object_count'], 10)
self.assertEquals(resp['status'], 404)
self.assertEquals(resp['versions'], "\xe1\xbd\x8a\x39")
def test_get_container_info_env(self):
cache_key = get_container_memcache_key("account", "cont")