]> granicus.if.org Git - python/commitdiff
SF #1022953: binascii.a2b_hqx("") raises SystemError
authorRaymond Hettinger <python@rcn.com>
Mon, 6 Sep 2004 22:58:37 +0000 (22:58 +0000)
committerRaymond Hettinger <python@rcn.com>
Mon, 6 Sep 2004 22:58:37 +0000 (22:58 +0000)
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.

Lib/test/test_binascii.py
Modules/binascii.c

index b01f0e00c4df07e4fdf5942a23591df034fb9a65..8df450456ee37a60e9a067bd898c123dd7e24a42 100755 (executable)
@@ -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)
 
index 5bd730c6f7e14b2470c29128f4fb6160dc380430..a374dc7cbfc44257e48bb587c4d8821da3443035 100644 (file)
@@ -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);