[pypy-commit] pypy default: Fix: _hashlib was just broken for any non-standard hash function.
arigo
noreply at buildbot.pypy.org
Sun Dec 11 12:48:39 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r50375:2e5b6dce5753
Date: 2011-12-11 12:48 +0100
http://bitbucket.org/pypy/pypy/changeset/2e5b6dce5753/
Log: Fix: _hashlib was just broken for any non-standard hash function.
Small extra clean-ups.
diff --git a/pypy/module/_hashlib/interp_hashlib.py b/pypy/module/_hashlib/interp_hashlib.py
--- a/pypy/module/_hashlib/interp_hashlib.py
+++ b/pypy/module/_hashlib/interp_hashlib.py
@@ -21,11 +21,11 @@
class W_Hash(Wrappable):
ctx = lltype.nullptr(ropenssl.EVP_MD_CTX.TO)
- _block_size = -1
def __init__(self, space, name):
self.name = name
- self.digest_size = self.compute_digest_size()
+ digest_type = self.digest_type_by_name(space)
+ self.digest_size = rffi.getintfield(digest_type, 'c_md_size')
# Allocate a lock for each HASH object.
# An optimization would be to not release the GIL on small requests,
@@ -34,21 +34,22 @@
ctx = lltype.malloc(ropenssl.EVP_MD_CTX.TO, flavor='raw')
rgc.add_memory_pressure(HASH_MALLOC_SIZE + self.digest_size)
+ ropenssl.EVP_DigestInit(ctx, digest_type)
self.ctx = ctx
- def initdigest(self, space, name):
- digest = ropenssl.EVP_get_digestbyname(name)
- if not digest:
- raise OperationError(space.w_ValueError,
- space.wrap("unknown hash function"))
- ropenssl.EVP_DigestInit(self.ctx, digest)
-
def __del__(self):
# self.lock.free()
if self.ctx:
ropenssl.EVP_MD_CTX_cleanup(self.ctx)
lltype.free(self.ctx, flavor='raw')
+ def digest_type_by_name(self, space):
+ digest_type = ropenssl.EVP_get_digestbyname(self.name)
+ if not digest_type:
+ raise OperationError(space.w_ValueError,
+ space.wrap("unknown hash function"))
+ return digest_type
+
def descr_repr(self, space):
addrstring = self.getaddrstring(space)
return space.wrap("<%s HASH object at 0x%s>" % (
@@ -87,7 +88,9 @@
return space.wrap(self.digest_size)
def get_block_size(self, space):
- return space.wrap(self.compute_block_size())
+ digest_type = self.digest_type_by_name(space)
+ block_size = rffi.getintfield(digest_type, 'c_block_size')
+ return space.wrap(block_size)
def _digest(self, space):
with lltype.scoped_alloc(ropenssl.EVP_MD_CTX.TO) as ctx:
@@ -99,36 +102,6 @@
ropenssl.EVP_MD_CTX_cleanup(ctx)
return rffi.charpsize2str(digest, digest_size)
- def compute_digest_size(self):
- # XXX This isn't the nicest way, but the EVP_MD_size OpenSSL
- # XXX function is defined as a C macro on OS X and would be
- # XXX significantly harder to implement in another way.
- # Values are digest sizes in bytes
- return {
- 'md5': 16, 'MD5': 16,
- 'sha1': 20, 'SHA1': 20,
- 'sha224': 28, 'SHA224': 28,
- 'sha256': 32, 'SHA256': 32,
- 'sha384': 48, 'SHA384': 48,
- 'sha512': 64, 'SHA512': 64,
- }.get(self.name, 0)
-
- def compute_block_size(self):
- if self._block_size != -1:
- return self._block_size
- # XXX This isn't the nicest way, but the EVP_MD_CTX_block_size
- # XXX OpenSSL function is defined as a C macro on some systems
- # XXX and would be significantly harder to implement in
- # XXX another way.
- self._block_size = {
- 'md5': 64, 'MD5': 64,
- 'sha1': 64, 'SHA1': 64,
- 'sha224': 64, 'SHA224': 64,
- 'sha256': 64, 'SHA256': 64,
- 'sha384': 128, 'SHA384': 128,
- 'sha512': 128, 'SHA512': 128,
- }.get(self.name, 0)
- return self._block_size
W_Hash.typedef = TypeDef(
'HASH',
@@ -142,11 +115,11 @@
digestsize=GetSetProperty(W_Hash.get_digest_size),
block_size=GetSetProperty(W_Hash.get_block_size),
)
+W_Hash.acceptable_as_base_class = False
@unwrap_spec(name=str, string='bufferstr')
def new(space, name, string=''):
w_hash = W_Hash(space, name)
- w_hash.initdigest(space, name)
w_hash.update(space, string)
return space.wrap(w_hash)
@@ -158,6 +131,6 @@
return new(space, name, string)
return new_hash
-for name in algorithms:
- newname = 'new_%s' % (name,)
- globals()[newname] = make_new_hash(name, newname)
+for _name in algorithms:
+ _newname = 'new_%s' % (_name,)
+ globals()[_newname] = make_new_hash(_name, _newname)
diff --git a/pypy/rlib/ropenssl.py b/pypy/rlib/ropenssl.py
--- a/pypy/rlib/ropenssl.py
+++ b/pypy/rlib/ropenssl.py
@@ -110,6 +110,10 @@
'struct GENERAL_NAME_st',
[('type', rffi.INT),
])
+ EVP_MD_st = rffi_platform.Struct(
+ 'EVP_MD',
+ [('md_size', rffi.INT),
+ ('block_size', rffi.INT)])
EVP_MD_SIZE = rffi_platform.SizeOf('EVP_MD')
EVP_MD_CTX_SIZE = rffi_platform.SizeOf('EVP_MD_CTX')
@@ -258,7 +262,7 @@
[BIO, rffi.VOIDP, rffi.VOIDP, rffi.VOIDP], X509)
EVP_MD_CTX = rffi.COpaquePtr('EVP_MD_CTX', compilation_info=eci)
-EVP_MD = rffi.COpaquePtr('EVP_MD', compilation_info=eci)
+EVP_MD = lltype.Ptr(EVP_MD_st)
OpenSSL_add_all_digests = external(
'OpenSSL_add_all_digests', [], lltype.Void)
More information about the pypy-commit
mailing list