diff options
author | Georg Brandl <georg@python.org> | 2008-12-28 11:54:53 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2008-12-28 11:54:53 (GMT) |
commit | 6425a2fa8f354e755f876f2dea708697e42cc9fd (patch) | |
tree | 45f306eac9c148cc56fe9aeef40fbbabc2a25067 /Objects | |
parent | e7d1e7e5d43e369db602bab35a6d5a47b6e5569e (diff) | |
download | cpython-6425a2fa8f354e755f876f2dea708697e42cc9fd.zip cpython-6425a2fa8f354e755f876f2dea708697e42cc9fd.tar.gz cpython-6425a2fa8f354e755f876f2dea708697e42cc9fd.tar.bz2 |
Backport r67974:
#4759: allow None as first argument of bytearray.translate(), for consistency with bytes.translate().
Also fix segfault for bytearray.translate(x, None) -- will backport this part to 3.0 and 2.6.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/bytearrayobject.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index d75eb53..97b0502 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1443,28 +1443,32 @@ bytes_translate(PyByteArrayObject *self, PyObject *args) PyObject *input_obj = (PyObject*)self; const char *output_start; Py_ssize_t inlen; - PyObject *result; + PyObject *result = NULL; int trans_table[256]; - PyObject *tableobj, *delobj = NULL; + PyObject *tableobj = NULL, *delobj = NULL; Py_buffer vtable, vdel; if (!PyArg_UnpackTuple(args, "translate", 1, 2, &tableobj, &delobj)) return NULL; - if (_getbuffer(tableobj, &vtable) < 0) + if (tableobj == Py_None) { + table = NULL; + tableobj = NULL; + } else if (_getbuffer(tableobj, &vtable) < 0) { return NULL; - - if (vtable.len != 256) { - PyErr_SetString(PyExc_ValueError, - "translation table must be 256 characters long"); - result = NULL; - goto done; + } else { + if (vtable.len != 256) { + PyErr_SetString(PyExc_ValueError, + "translation table must be 256 characters long"); + goto done; + } + table = (const char*)vtable.buf; } if (delobj != NULL) { if (_getbuffer(delobj, &vdel) < 0) { - result = NULL; + delobj = NULL; /* don't try to release vdel buffer on exit */ goto done; } } @@ -1473,7 +1477,6 @@ bytes_translate(PyByteArrayObject *self, PyObject *args) vdel.len = 0; } - table = (const char *)vtable.buf; inlen = PyByteArray_GET_SIZE(input_obj); result = PyByteArray_FromStringAndSize((char *)NULL, inlen); if (result == NULL) @@ -1481,7 +1484,7 @@ bytes_translate(PyByteArrayObject *self, PyObject *args) output_start = output = PyByteArray_AsString(result); input = PyByteArray_AS_STRING(input_obj); - if (vdel.len == 0) { + if (vdel.len == 0 && table != NULL) { /* If no deletions are required, use faster code */ for (i = inlen; --i >= 0; ) { c = Py_CHARMASK(*input++); @@ -1489,9 +1492,14 @@ bytes_translate(PyByteArrayObject *self, PyObject *args) } goto done; } - - for (i = 0; i < 256; i++) - trans_table[i] = Py_CHARMASK(table[i]); + + if (table == NULL) { + for (i = 0; i < 256; i++) + trans_table[i] = Py_CHARMASK(i); + } else { + for (i = 0; i < 256; i++) + trans_table[i] = Py_CHARMASK(table[i]); + } for (i = 0; i < vdel.len; i++) trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1; @@ -1507,7 +1515,8 @@ bytes_translate(PyByteArrayObject *self, PyObject *args) PyByteArray_Resize(result, output - output_start); done: - PyBuffer_Release(&vtable); + if (tableobj != NULL) + PyBuffer_Release(&vtable); if (delobj != NULL) PyBuffer_Release(&vdel); return result; |