Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 78cb491

Browse files
committed
Merged revisions 66496 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r66496 | benjamin.peterson | 2008-09-17 20:22:16 -0500 (Wed, 17 Sep 2008) | 1 line fix possible integer overflows in _hashopenssl #3886 ........
1 parent 1308c26 commit 78cb491

2 files changed

Lines changed: 59 additions & 15 deletions

File tree

Lib/test/test_hashlib.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import hashlib
1010
import unittest
1111
from test import support
12-
12+
from test.support import _4G, precisionbigmemtest
1313

1414
def hexstr(s):
1515
assert isinstance(s, bytes), repr(s)
@@ -55,7 +55,6 @@ def test_large_update(self):
5555
m2.update(aas + bees + cees)
5656
self.assertEqual(m1.digest(), m2.digest())
5757

58-
5958
def check(self, name, data, digest):
6059
# test the direct constructors
6160
computed = getattr(hashlib, name)(data).hexdigest()
@@ -76,6 +75,21 @@ def test_case_md5_2(self):
7675
b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
7776
'd174ab98d277d9f5a5611c2c9f419d9f')
7877

78+
@precisionbigmemtest(size=_4G + 5, memuse=1)
79+
def test_case_md5_huge(self, size):
80+
if size == _4G + 5:
81+
try:
82+
self.check('md5', 'A'*size, 'c9af2dff37468ce5dfee8f2cfc0a9c6d')
83+
except OverflowError:
84+
pass # 32-bit arch
85+
86+
@precisionbigmemtest(size=_4G - 1, memuse=1)
87+
def test_case_md5_uintmax(self, size):
88+
if size == _4G - 1:
89+
try:
90+
self.check('md5', 'A'*size, '28138d306ff1b8281f1a9067e1a1a2b3')
91+
except OverflowError:
92+
pass # 32-bit arch
7993

8094
# use the three examples from Federal Information Processing Standards
8195
# Publication 180-1, Secure Hash Standard, 1995 April 17

Modules/_hashopenssl.c

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
/* EVP is the preferred interface to hashing in OpenSSL */
2020
#include <openssl/evp.h>
2121

22+
#define MUNCH_SIZE INT_MAX
23+
2224

2325
#ifndef HASH_OBJ_CONSTRUCTOR
2426
#define HASH_OBJ_CONSTRUCTOR 0
@@ -182,10 +184,17 @@ EVP_update(EVPobject *self, PyObject *args)
182184
return NULL;
183185

184186
MY_GET_BUFFER_VIEW_OR_ERROUT(obj, &view);
185-
186-
EVP_DigestUpdate(&self->ctx, (unsigned char*)view.buf,
187-
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));
188-
187+
if (view.len > 0 && view.len <= MUNCH_SIZE) {
188+
EVP_DigestUpdate(&self->ctx, view.buf, view.len);
189+
} else {
190+
Py_ssize_t offset = 0, len = view.len;
191+
while (len) {
192+
unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len;
193+
EVP_DigestUpdate(&self->ctx, (unsigned char*)view.buf + offset, process);
194+
len -= process;
195+
offset += process;
196+
}
197+
}
189198
PyBuffer_Release(&view);
190199

191200
Py_INCREF(Py_None);
@@ -284,11 +293,21 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
284293
Py_INCREF(self->name);
285294

286295
if (data_obj) {
287-
EVP_DigestUpdate(&self->ctx, (unsigned char*)view.buf,
288-
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));
296+
if (len > 0 && len <= MUNCH_SIZE) {
297+
EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t,
298+
unsigned int));
299+
} else {
300+
Py_ssize_t offset = 0, len = view.len;
301+
while (len) {
302+
unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len;
303+
EVP_DigestUpdate(&self->ctx, (unsigned char*)view.buf + offset, process);
304+
len -= process;
305+
offset += process;
306+
}
307+
}
289308
PyBuffer_Release(&view);
290309
}
291-
310+
292311
return 0;
293312
}
294313
#endif
@@ -357,7 +376,7 @@ static PyTypeObject EVPtype = {
357376
static PyObject *
358377
EVPnew(PyObject *name_obj,
359378
const EVP_MD *digest, const EVP_MD_CTX *initial_ctx,
360-
const unsigned char *cp, unsigned int len)
379+
const unsigned char *cp, Py_ssize_t len)
361380
{
362381
EVPobject *self;
363382

@@ -375,8 +394,20 @@ EVPnew(PyObject *name_obj,
375394
EVP_DigestInit(&self->ctx, digest);
376395
}
377396

378-
if (cp && len)
379-
EVP_DigestUpdate(&self->ctx, cp, len);
397+
if (cp && len) {
398+
if (len > 0 && len <= MUNCH_SIZE) {
399+
EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t,
400+
unsigned int));
401+
} else {
402+
Py_ssize_t offset = 0;
403+
while (len) {
404+
unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len;
405+
EVP_DigestUpdate(&self->ctx, cp + offset, process);
406+
len -= process;
407+
offset += process;
408+
}
409+
}
410+
}
380411

381412
return (PyObject *)self;
382413
}
@@ -417,8 +448,7 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
417448

418449
digest = EVP_get_digestbyname(name);
419450

420-
ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf,
421-
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));
451+
ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, view.len);
422452

423453
if (data_obj)
424454
PyBuffer_Release(&view);
@@ -452,7 +482,7 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
452482
NULL, \
453483
CONST_new_ ## NAME ## _ctx_p, \
454484
(unsigned char*)view.buf, \
455-
Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int)); \
485+
view.len); \
456486
\
457487
if (data_obj) \
458488
PyBuffer_Release(&view); \

0 commit comments

Comments
 (0)