diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index b01f0e00c4d..8df450456ee 100755 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -148,6 +148,16 @@ class BinASCIITest(unittest.TestCase): "0"*75+"=\r\n=FF\r\n=FF\r\n=FF" ) + def test_empty_string(self): + # A test for SF bug #1022953. Make sure SystemError is not raised. + for n in ['b2a_qp', 'a2b_hex', 'b2a_base64', 'a2b_uu', 'a2b_qp', + 'b2a_hex', 'unhexlify', 'hexlify', 'crc32', 'b2a_hqx', + 'a2b_hqx', 'a2b_base64', 'rlecode_hqx', 'b2a_uu', + 'rledecode_hqx']: + f = getattr(binascii, n) + f('') + binascii.crc_hqx('', 0) + def test_main(): test_support.run_unittest(BinASCIITest) diff --git a/Modules/binascii.c b/Modules/binascii.c index 5bd730c6f7e..a374dc7cbfc 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);