diff --git a/swh/model/hashutil.py b/swh/model/hashutil.py --- a/swh/model/hashutil.py +++ b/swh/model/hashutil.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 The Software Heritage developers +# Copyright (C) 2015-2017 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -6,9 +6,10 @@ import binascii import functools import hashlib -from io import BytesIO import os +from io import BytesIO + # supported hashing algorithms ALGORITHMS = set(['sha1', 'sha256', 'sha1_git']) @@ -64,7 +65,7 @@ ValueError if algo is unknown, or length is missing for a git-specific hash. """ - if algo not in ALGORITHMS: + if algo not in ALGORITHMS and ':' not in algo: raise ValueError('Unexpected hashing algorithm %s, ' 'expected one of %s' % (algo, ', '.join(sorted(ALGORITHMS)))) @@ -75,6 +76,11 @@ raise ValueError('Missing length for git hashing algorithm') base_algo = algo[:-4] h = _new_git_hash(base_algo, 'blob', length) + elif ':' in algo: # variable length hashing algorithms + _algo = algo.split(':') + base_algo = _algo[0] + variable_length = int(_algo[1]) + h = hashlib.new('%s%s' % (base_algo, variable_length)) else: h = hashlib.new(algo) diff --git a/swh/model/tests/test_hashutil.py b/swh/model/tests/test_hashutil.py --- a/swh/model/tests/test_hashutil.py +++ b/swh/model/tests/test_hashutil.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 The Software Heritage developers +# Copyright (C) 2015-2017 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -8,6 +8,7 @@ import unittest from nose.tools import istest +from unittest.mock import patch from swh.model import hashutil @@ -110,3 +111,31 @@ hash = self.checksums[type] self.assertEquals(hashutil.hash_to_bytes(hex), hash) self.assertEquals(hashutil.hash_to_bytes(hash), hash) + + @istest + def new_hash_unsupported_hashing_algorithm(self): + try: + hashutil._new_hash('blake2:10') + except ValueError as e: + self.assertEquals(str(e), + 'unsupported hash type blake210') + + @patch('swh.model.hashutil.hashlib') + @istest + def new_hash_blake2b(self, mock_hashlib): + mock_hashlib.new.return_value = 'some-hashlib-object' + + h = hashutil._new_hash('blake2b:512') + + self.assertEquals(h, 'some-hashlib-object') + mock_hashlib.new.assert_called_with('blake2b512') + + @patch('swh.model.hashutil.hashlib') + @istest + def new_hash_blake2s(self, mock_hashlib): + mock_hashlib.new.return_value = 'some-hashlib-object' + + h = hashutil._new_hash('blake2s:256') + + self.assertEquals(h, 'some-hashlib-object') + mock_hashlib.new.assert_called_with('blake2s256')