summaryrefslogtreecommitdiff
path: root/Modules/binascii.c
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2004-09-06 22:58:37 +0000
committerRaymond Hettinger <python@rcn.com>2004-09-06 22:58:37 +0000
commit658717ed117c8002d084359a3ad2f88ca7df8c99 (patch)
tree1e884ec59e3510ccc4db99290cc133f6550b43a1 /Modules/binascii.c
parent8158e849305d0e0ab3e19cdc93a86bb7d5fc0651 (diff)
downloadcpython-git-658717ed117c8002d084359a3ad2f88ca7df8c99.tar.gz
SF #1022953: binascii.a2b_hqx("") raises SystemError
Several functions adopted the strategy of altering a full lengthed string copy and resizing afterwards. That would fail if the initial string was short enough (0 or 1) to be interned. Interning precluded the subsequent resizing operation. The solution was to make sure the initial string was at least two characters long. Added tests to verify that all binascii functions do not crater when given an empty string argument.
Diffstat (limited to 'Modules/binascii.c')
-rw-r--r--Modules/binascii.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/Modules/binascii.c b/Modules/binascii.c
index 5bd730c6f7..a374dc7cbf 100644
--- a/Modules/binascii.c
+++ b/Modules/binascii.c
@@ -276,7 +276,7 @@ binascii_b2a_uu(PyObject *self, PyObject *args)
}
/* We're lazy and allocate to much (fixed up later) */
- if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2)) == NULL )
+ if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2+2)) == NULL )
return NULL;
ascii_data = (unsigned char *)PyString_AsString(rv);
@@ -491,8 +491,10 @@ binascii_a2b_hqx(PyObject *self, PyObject *args)
if ( !PyArg_ParseTuple(args, "t#:a2b_hqx", &ascii_data, &len) )
return NULL;
- /* Allocate a string that is too big (fixed later) */
- if ( (rv=PyString_FromStringAndSize(NULL, len)) == NULL )
+ /* Allocate a string that is too big (fixed later)
+ Add two to the initial length to prevent interning which
+ would preclude subsequent resizing. */
+ if ( (rv=PyString_FromStringAndSize(NULL, len+2)) == NULL )
return NULL;
bin_data = (unsigned char *)PyString_AsString(rv);
@@ -528,6 +530,15 @@ binascii_a2b_hqx(PyObject *self, PyObject *args)
Py_DECREF(rv);
return NULL;
}
+
+
+ assert(PyString_Check(rv));
+ assert((bin_data - (unsigned char *)PyString_AsString(rv)) >= 0);
+ assert(!PyString_CHECK_INTERNED(rv));
+
+ assert(rv->ob_refcnt == 1);
+
+
_PyString_Resize(
&rv, (bin_data - (unsigned char *)PyString_AsString(rv)));
if (rv) {
@@ -553,7 +564,7 @@ binascii_rlecode_hqx(PyObject *self, PyObject *args)
return NULL;
/* Worst case: output is twice as big as input (fixed later) */
- if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
+ if ( (rv=PyString_FromStringAndSize(NULL, len*2+2)) == NULL )
return NULL;
out_data = (unsigned char *)PyString_AsString(rv);
@@ -602,7 +613,7 @@ binascii_b2a_hqx(PyObject *self, PyObject *args)
return NULL;
/* Allocate a buffer that is at least large enough */
- if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
+ if ( (rv=PyString_FromStringAndSize(NULL, len*2+2)) == NULL )
return NULL;
ascii_data = (unsigned char *)PyString_AsString(rv);