Commit 816b0a4e authored by Sofia Papagiannaki's avatar Sofia Papagiannaki

Pithos: Catch invalid hashmap input

Refs: #3745
parent ae1abe6c
......@@ -66,7 +66,7 @@ from pithos.api import settings
from pithos.backends.base import (
NotAllowedError, QuotaError, ContainerNotEmpty, ItemNotExists,
VersionNotExists, ContainerExists)
VersionNotExists, ContainerExists, InvalidHash)
from pithos.backends.filter import parse_filters
......@@ -1115,6 +1115,8 @@ def object_write(request, v_account, v_container, v_object):
raise faults.BadRequest('Invalid sharing header')
except QuotaError, e:
raise faults.RequestEntityTooLarge('Quota error: %s' % e)
except InvalidHash, e:
raise faults.BadRequest('Invalid hash: %s' % e)
if not checksum and UPDATE_MD5:
# Update the MD5 after the hashmap, as there may be missing hashes.
checksum = hashmap_md5(request.backend, hashmap, size)
......
......@@ -733,6 +733,27 @@ class ObjectPut(PithosAPITest):
self.assertEqual(r.status_code, 200)
self.assertEqual(r.content, data)
def test_create_object_by_invalid_hashmap(self):
cname = self.container
block_size = pithos_settings.BACKEND_BLOCK_SIZE
# upload an object
oname, data = self.upload_object(cname, length=block_size + 1)[:-1]
# get it hashmap
url = join_urls(self.pithos_path, self.user, cname, oname)
r = self.get('%s?hashmap=&format=json' % url)
data = r.content
try:
hashmap = json.loads(data)
except:
self.fail('JSON format expected')
oname = get_random_name()
url = join_urls(self.pithos_path, self.user, cname, oname)
hashmap['hashes'] = [get_random_name()]
r = self.put('%s?hashmap=' % url, data=json.dumps(hashmap))
self.assertEqual(r.status_code, 400)
class ObjectPutCopy(PithosAPITest):
def setUp(self):
......
......@@ -68,6 +68,8 @@ class ItemNotExists(NameError):
class VersionNotExists(IndexError):
pass
class InvalidHash(TypeError):
pass
class BaseBackend(object):
"""Abstract backend class.
......
......@@ -48,7 +48,8 @@ except ImportError:
from base import (DEFAULT_ACCOUNT_QUOTA, DEFAULT_CONTAINER_QUOTA,
DEFAULT_CONTAINER_VERSIONING, NotAllowedError, QuotaError,
BaseBackend, AccountExists, ContainerExists, AccountNotEmpty,
ContainerNotEmpty, ItemNotExists, VersionNotExists)
ContainerNotEmpty, ItemNotExists, VersionNotExists,
InvalidHash)
class DisabledAstakosClient(object):
......@@ -930,7 +931,7 @@ class ModularBackend(BaseBackend):
props = self._get_version(node, version)
if props[self.HASH] is None:
return 0, ()
hashmap = self.store.map_get(binascii.unhexlify(props[self.HASH]))
hashmap = self.store.map_get(self._unhexlify_hash(props[self.HASH]))
return props[self.SIZE], [binascii.hexlify(x) for x in hashmap]
def _update_object_hash(self, user, account, container, name, size, type,
......@@ -1015,7 +1016,7 @@ class ModularBackend(BaseBackend):
if size == 0: # No such thing as an empty hashmap.
hashmap = [self.put_block('')]
map = HashMap(self.block_size, self.hash_algorithm)
map.extend([binascii.unhexlify(x) for x in hashmap])
map.extend([self._unhexlify_hash(x) for x in hashmap])
missing = self.store.block_search(map)
if missing:
ie = IndexError()
......@@ -1273,7 +1274,7 @@ class ModularBackend(BaseBackend):
"""Return a block's data."""
logger.debug("get_block: %s", hash)
block = self.store.block_get(binascii.unhexlify(hash))
block = self.store.block_get(self._unhexlify_hash(hash))
if not block:
raise ItemNotExists('Block does not exist')
return block
......@@ -1290,7 +1291,7 @@ class ModularBackend(BaseBackend):
logger.debug("update_block: %s %s %s", hash, len(data), offset)
if offset == 0 and len(data) == self.block_size:
return self.put_block(data)
h = self.store.block_update(binascii.unhexlify(hash), offset, data)
h = self.store.block_update(self._unhexlify_hash(hash), offset, data)
return binascii.hexlify(h)
# Path functions.
......@@ -1730,3 +1731,9 @@ class ModularBackend(BaseBackend):
return False
else:
return True
def _unhexlify_hash(self, hash):
try:
return binascii.unhexlify(hash)
except TypeError:
raise InvalidHash(hash)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment