summaryrefslogtreecommitdiff
path: root/Python/pystrhex.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/pystrhex.c')
-rw-r--r--Python/pystrhex.c50
1 files changed, 26 insertions, 24 deletions
diff --git a/Python/pystrhex.c b/Python/pystrhex.c
index 9d34f71a2e..7e4fad3032 100644
--- a/Python/pystrhex.c
+++ b/Python/pystrhex.c
@@ -8,12 +8,9 @@ static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen,
const PyObject* sep, int bytes_per_sep_group,
const int return_bytes)
{
- PyObject *retval;
- Py_UCS1* retbuf;
- Py_ssize_t i, j, resultlen = 0;
- Py_UCS1 sep_char = 0;
- unsigned int abs_bytes_per_sep;
+ assert(arglen >= 0);
+ Py_UCS1 sep_char = 0;
if (sep) {
Py_ssize_t seplen = PyObject_Length((PyObject*)sep);
if (seplen < 0) {
@@ -31,9 +28,11 @@ static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen,
return NULL;
}
sep_char = PyUnicode_READ_CHAR(sep, 0);
- } else if (PyBytes_Check(sep)) {
+ }
+ else if (PyBytes_Check(sep)) {
sep_char = PyBytes_AS_STRING(sep)[0];
- } else {
+ }
+ else {
PyErr_SetString(PyExc_TypeError, "sep must be str or bytes.");
return NULL;
}
@@ -41,12 +40,13 @@ static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen,
PyErr_SetString(PyExc_ValueError, "sep must be ASCII.");
return NULL;
}
- } else {
+ }
+ else {
bytes_per_sep_group = 0;
}
- assert(arglen >= 0);
- abs_bytes_per_sep = abs(bytes_per_sep_group);
+ unsigned int abs_bytes_per_sep = abs(bytes_per_sep_group);
+ Py_ssize_t resultlen = 0;
if (bytes_per_sep_group && arglen > 0) {
/* How many sep characters we'll be inserting. */
resultlen = (arglen - 1) / abs_bytes_per_sep;
@@ -62,26 +62,32 @@ static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen,
abs_bytes_per_sep = 0;
}
+ PyObject *retval;
+ Py_UCS1 *retbuf;
if (return_bytes) {
/* If _PyBytes_FromSize() were public we could avoid malloc+copy. */
- retbuf = (Py_UCS1*) PyMem_Malloc(resultlen);
- if (!retbuf)
- return PyErr_NoMemory();
- retval = NULL; /* silence a compiler warning, assigned later. */
- } else {
+ retval = PyBytes_FromStringAndSize(NULL, resultlen);
+ if (!retval) {
+ return NULL;
+ }
+ retbuf = (Py_UCS1 *)PyBytes_AS_STRING(retval);
+ }
+ else {
retval = PyUnicode_New(resultlen, 127);
- if (!retval)
+ if (!retval) {
return NULL;
+ }
retbuf = PyUnicode_1BYTE_DATA(retval);
}
/* Hexlify */
+ Py_ssize_t i, j;
for (i=j=0; i < arglen; ++i) {
- assert(j < resultlen);
+ assert((j + 1) < resultlen);
unsigned char c;
- c = (argbuf[i] >> 4) & 0xf;
+ c = (argbuf[i] >> 4) & 0x0f;
retbuf[j++] = Py_hexdigits[c];
- c = argbuf[i] & 0xf;
+ c = argbuf[i] & 0x0f;
retbuf[j++] = Py_hexdigits[c];
if (bytes_per_sep_group && i < arglen - 1) {
Py_ssize_t anchor;
@@ -93,12 +99,8 @@ static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen,
}
assert(j == resultlen);
- if (return_bytes) {
- retval = PyBytes_FromStringAndSize((const char *)retbuf, resultlen);
- PyMem_Free(retbuf);
- }
#ifdef Py_DEBUG
- else {
+ if (!return_bytes) {
assert(_PyUnicode_CheckConsistency(retval, 1));
}
#endif