Ticket #16: reupdate.txt

File reupdate.txt, 4.9 KB (added by zooko, at 2009-03-03T03:46:44Z)
Line 
1Mon Mar  2 20:30:25 MST 2009  zooko@zooko.com
2  * allow sha256 .update() after .digest()
3  Also switch the way casting of the de-allocator is done to narrow the scope of what gets cast.
4  This patch comes with a unit test, which it fails, showing that there is a bug in it.
5
6New patches:
7
8[allow sha256 .update() after .digest()
9zooko@zooko.com**20090303033025
10 Ignore-this: 57c079abc00e8ee8a51e40fc773789e6
11 Also switch the way casting of the de-allocator is done to narrow the scope of what gets cast.
12 This patch comes with a unit test, which it fails, showing that there is a bug in it.
13] {
14hunk ./pycryptopp/hash/sha256module.cpp 27
15 
16     /* internal */
17     CryptoPP::SHA256* h;
18-    PyStringObject* digest;
19 } SHA256;
20 
21 PyDoc_STRVAR(SHA256__doc__,
22hunk ./pycryptopp/hash/sha256module.cpp 36
23 
24 static PyObject *
25 SHA256_update(SHA256* self, PyObject* msgobj) {
26-    if (self->digest)
27-        return PyErr_Format(sha256_error, "Precondition violation: once .digest() has been called you are required to never call .update() again.");
28-
29     const char *msg;
30     Py_ssize_t msgsize;
31     if (PyString_AsStringAndSize(msgobj, const_cast<char**>(&msg), &msgsize))
32hunk ./pycryptopp/hash/sha256module.cpp 50
33 
34 static PyObject *
35 SHA256_digest(SHA256* self, PyObject* dummy) {
36-    if (!self->digest) {
37-        self->digest = reinterpret_cast<PyStringObject*>(PyString_FromStringAndSize(NULL, self->h->DigestSize()));
38-        if (!self->digest)
39-            return NULL;
40-        self->h->Final(reinterpret_cast<byte*>(PyString_AS_STRING(self->digest)));
41-    }
42+    // TODO: detect digest-size at compile time not runtime
43+    PyStringObject* result = reinterpret_cast<PyStringObject*>(PyString_FromStringAndSize(NULL, self->h->DigestSize()));
44+    if (!result)
45+        return NULL;
46+
47+    self->h->Final(reinterpret_cast<byte*>(PyString_AS_STRING(result)));
48 
49hunk ./pycryptopp/hash/sha256module.cpp 57
50-    Py_INCREF(self->digest);
51-    return reinterpret_cast<PyObject*>(self->digest);
52+    return reinterpret_cast<PyObject*>(result);
53 }
54 
55 PyDoc_STRVAR(SHA256_digest__doc__,
56hunk ./pycryptopp/hash/sha256module.cpp 99
57     self->h = new CryptoPP::SHA256();
58     if (!self->h)
59         return PyErr_NoMemory();
60-    self->digest = NULL;
61     return reinterpret_cast<PyObject*>(self);
62 }
63 
64hunk ./pycryptopp/hash/sha256module.cpp 103
65 static void
66-SHA256_dealloc(SHA256* self) {
67-    Py_XDECREF(self->digest);
68-    delete self->h;
69-    self->ob_type->tp_free((PyObject*)self);
70+SHA256_dealloc(PyObject* self) {
71+    SHA256* typedself = reinterpret_cast<SHA256*>(self);
72+    delete typedself->h;
73+    typedself->ob_type->tp_free(self);
74 }
75 
76 static int
77hunk ./pycryptopp/hash/sha256module.cpp 128
78     "sha256.SHA256", /*tp_name*/
79     sizeof(SHA256),             /*tp_basicsize*/
80     0,                         /*tp_itemsize*/
81-    reinterpret_cast<destructor>(SHA256_dealloc), /*tp_dealloc*/
82+    SHA256_dealloc, /*tp_dealloc*/
83     0,                         /*tp_print*/
84     0,                         /*tp_getattr*/
85     0,                         /*tp_setattr*/
86hunk ./pycryptopp/hash/sha256module.cpp 159
87     0,                         /* tp_descr_get */
88     0,                         /* tp_descr_set */
89     0,                         /* tp_dictoffset */
90-    //reinterpret_cast<initproc>(SHA256_init),               /* tp_init */
91     SHA256_init,               /* tp_init */
92     0,                         /* tp_alloc */
93     SHA256_new,                /* tp_new */
94hunk ./pycryptopp/test/test_sha256.py 67
95 
96     def test_constructor_type_check(self):
97         self.failUnlessRaises(TypeError, sha256.SHA256, None)
98-                             
99+
100     def test_update_type_check(self):
101         h = sha256.SHA256()
102         self.failUnlessRaises(TypeError, h.update, None)
103hunk ./pycryptopp/test/test_sha256.py 79
104         d2 = h.digest()
105         self.failUnlessEqual(d1, d2)
106 
107-    def test_digest_then_update_fail(self):
108+    def test_digest_then_update(self):
109         h = sha256.SHA256()
110         d1 = h.digest()
111hunk ./pycryptopp/test/test_sha256.py 82
112-        try:
113-            h.update("oops")
114-        except sha256.Error, le:
115-            self.failUnless("digest() has been called" in str(le), le)
116+        h.update("MORE")
117+        d2 = h.digest()
118+        self.failIfEqual(d1, d2)
119+
120+        h2 = sha256.SHA256()
121+        h2.update("MORE")
122+        d3 = h2.digest()
123+
124+        self.failUnlessEqual(d2, d3)
125+
126+        h = sha256.SHA256()
127+        h.update("abcde")
128+        d4 = h.digest()
129+        h.update("fghij")
130+        d5 = h.digest()
131+        self.failIfEqual(d4, d5)
132+
133+        h = sha256.SHA256()
134+        h.update("abcdefghij")
135+        d6 = h.digest()
136+        self.failUnlessEqual(d5, d6)
137+    test_digest_then_update.todo = "todo: make this work"
138+
139 
140 VECTS_RE=re.compile("\nLen = ([0-9]+)\nMsg = ([0-9a-f]+)\nMD = ([0-9a-f]+)")
141 
142}
143
144Context:
145
146[TAG pycryptopp-0.5.12
147zooko@zooko.com**20081119210020
148 Ignore-this: 73b90e9bd66f02ef953e441fae9d5917
149]
150Patch bundle hash:
151a0e80c20740840f50be8acf6999bdb4e4fee408a