diff options
Diffstat (limited to 'Modules/binascii.c')
-rw-r--r-- | Modules/binascii.c | 686 |
1 files changed, 361 insertions, 325 deletions
diff --git a/Modules/binascii.c b/Modules/binascii.c index 829bde8..c9309ce 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -183,6 +183,27 @@ static unsigned short crctab_hqx[256] = { 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, }; +/*[clinic input] +output preset file +module binascii +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=44c6f840ce708f0c]*/ + +/*[python input] + +class ascii_buffer_converter(CConverter): + type = 'Py_buffer' + converter = 'ascii_buffer_converter' + impl_by_reference = True + c_default = "{NULL, NULL}" + + def cleanup(self): + name = self.name + return "".join(["if (", name, ".obj)\n PyBuffer_Release(&", name, ");\n"]) + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=3eb7b63610da92cd]*/ + static int ascii_buffer_converter(PyObject *arg, Py_buffer *buf) { @@ -207,26 +228,34 @@ ascii_buffer_converter(PyObject *arg, Py_buffer *buf) if (PyObject_GetBuffer(arg, buf, PyBUF_SIMPLE) != 0) { PyErr_Format(PyExc_TypeError, "argument should be bytes, buffer or ASCII string, " - "not %R", Py_TYPE(arg)); + "not '%.100s'", Py_TYPE(arg)->tp_name); return 0; } if (!PyBuffer_IsContiguous(buf, 'C')) { PyErr_Format(PyExc_TypeError, "argument should be a contiguous buffer, " - "not %R", Py_TYPE(arg)); + "not '%.100s'", Py_TYPE(arg)->tp_name); PyBuffer_Release(buf); return 0; } return Py_CLEANUP_SUPPORTED; } +#include "clinic/binascii.c.h" + +/*[clinic input] +binascii.a2b_uu -PyDoc_STRVAR(doc_a2b_uu, "(ascii) -> bin. Decode a line of uuencoded data"); + data: ascii_buffer + / + +Decode a line of uuencoded data. +[clinic start generated code]*/ static PyObject * -binascii_a2b_uu(PyObject *self, PyObject *args) +binascii_a2b_uu_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=5779f39b0b48459f input=7cafeaf73df63d1c]*/ { - Py_buffer pascii; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -234,10 +263,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args) PyObject *rv; Py_ssize_t ascii_len, bin_len; - if ( !PyArg_ParseTuple(args, "O&:a2b_uu", ascii_buffer_converter, &pascii) ) - return NULL; - ascii_data = pascii.buf; - ascii_len = pascii.len; + ascii_data = data->buf; + ascii_len = data->len; assert(ascii_len >= 0); @@ -246,10 +273,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args) ascii_len--; /* Allocate the buffer */ - if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) { - PyBuffer_Release(&pascii); + if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) return NULL; - } bin_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) { @@ -269,7 +294,6 @@ binascii_a2b_uu(PyObject *self, PyObject *args) */ if ( this_ch < ' ' || this_ch > (' ' + 64)) { PyErr_SetString(Error, "Illegal char"); - PyBuffer_Release(&pascii); Py_DECREF(rv); return NULL; } @@ -298,21 +322,26 @@ binascii_a2b_uu(PyObject *self, PyObject *args) if ( this_ch != ' ' && this_ch != ' '+64 && this_ch != '\n' && this_ch != '\r' ) { PyErr_SetString(Error, "Trailing garbage"); - PyBuffer_Release(&pascii); Py_DECREF(rv); return NULL; } } - PyBuffer_Release(&pascii); return rv; } -PyDoc_STRVAR(doc_b2a_uu, "(bin) -> ascii. Uuencode line of data"); +/*[clinic input] +binascii.b2a_uu + + data: Py_buffer + / + +Uuencode line of data. +[clinic start generated code]*/ static PyObject * -binascii_b2a_uu(PyObject *self, PyObject *args) +binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=181021b69bb9a414 input=00fdf458ce8b465b]*/ { - Py_buffer pbin; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -320,22 +349,17 @@ binascii_b2a_uu(PyObject *self, PyObject *args) PyObject *rv; Py_ssize_t bin_len; - if ( !PyArg_ParseTuple(args, "y*:b2a_uu", &pbin) ) - return NULL; - bin_data = pbin.buf; - bin_len = pbin.len; + bin_data = data->buf; + bin_len = data->len; if ( bin_len > 45 ) { /* The 45 is a limit that appears in all uuencode's */ PyErr_SetString(Error, "At most 45 bytes at once"); - PyBuffer_Release(&pbin); return NULL; } /* We're lazy and allocate to much (fixed up later) */ - if ( (rv=PyBytes_FromStringAndSize(NULL, 2 + (bin_len+2)/3*4)) == NULL ) { - PyBuffer_Release(&pbin); + if ( (rv=PyBytes_FromStringAndSize(NULL, 2 + (bin_len+2)/3*4)) == NULL ) return NULL; - } ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); /* Store the length */ @@ -361,10 +385,8 @@ binascii_b2a_uu(PyObject *self, PyObject *args) if (_PyBytes_Resize(&rv, (ascii_data - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_DECREF(rv); - rv = NULL; + Py_CLEAR(rv); } - PyBuffer_Release(&pbin); return rv; } @@ -394,12 +416,19 @@ binascii_find_valid(unsigned char *s, Py_ssize_t slen, int num) return ret; } -PyDoc_STRVAR(doc_a2b_base64, "(ascii) -> bin. Decode a line of base64 data"); +/*[clinic input] +binascii.a2b_base64 + + data: ascii_buffer + / + +Decode a line of base64 data. +[clinic start generated code]*/ static PyObject * -binascii_a2b_base64(PyObject *self, PyObject *args) +binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=3e351b702bed56d2 input=5872acf6e1cac243]*/ { - Py_buffer pascii; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -408,25 +437,19 @@ binascii_a2b_base64(PyObject *self, PyObject *args) Py_ssize_t ascii_len, bin_len; int quad_pos = 0; - if ( !PyArg_ParseTuple(args, "O&:a2b_base64", ascii_buffer_converter, &pascii) ) - return NULL; - ascii_data = pascii.buf; - ascii_len = pascii.len; + ascii_data = data->buf; + ascii_len = data->len; assert(ascii_len >= 0); - if (ascii_len > PY_SSIZE_T_MAX - 3) { - PyBuffer_Release(&pascii); + if (ascii_len > PY_SSIZE_T_MAX - 3) return PyErr_NoMemory(); - } bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */ /* Allocate the buffer */ - if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) { - PyBuffer_Release(&pascii); + if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) return NULL; - } bin_data = (unsigned char *)PyBytes_AS_STRING(rv); bin_len = 0; @@ -479,7 +502,6 @@ binascii_a2b_base64(PyObject *self, PyObject *args) } if (leftbits != 0) { - PyBuffer_Release(&pascii); PyErr_SetString(Error, "Incorrect padding"); Py_DECREF(rv); return NULL; @@ -491,24 +513,30 @@ binascii_a2b_base64(PyObject *self, PyObject *args) */ if (bin_len > 0) { if (_PyBytes_Resize(&rv, bin_len) < 0) { - Py_DECREF(rv); - rv = NULL; + Py_CLEAR(rv); } } else { Py_DECREF(rv); rv = PyBytes_FromStringAndSize("", 0); } - PyBuffer_Release(&pascii); return rv; } -PyDoc_STRVAR(doc_b2a_base64, "(bin) -> ascii. Base64-code line of data"); + +/*[clinic input] +binascii.b2a_base64 + + data: Py_buffer + / + +Base64-code line of data. +[clinic start generated code]*/ static PyObject * -binascii_b2a_base64(PyObject *self, PyObject *args) +binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=3cd61fbee2913285 input=14ec4e47371174a9]*/ { - Py_buffer pbuf; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -516,26 +544,21 @@ binascii_b2a_base64(PyObject *self, PyObject *args) PyObject *rv; Py_ssize_t bin_len; - if ( !PyArg_ParseTuple(args, "y*:b2a_base64", &pbuf) ) - return NULL; - bin_data = pbuf.buf; - bin_len = pbuf.len; + bin_data = data->buf; + bin_len = data->len; assert(bin_len >= 0); if ( bin_len > BASE64_MAXBIN ) { PyErr_SetString(Error, "Too much data for base64 line"); - PyBuffer_Release(&pbuf); return NULL; } /* We're lazy and allocate too much (fixed up later). "+3" leaves room for up to two pad characters and a trailing newline. Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */ - if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL ) { - PyBuffer_Release(&pbuf); + if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL ) return NULL; - } ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; bin_len > 0 ; bin_len--, bin_data++ ) { @@ -563,19 +586,24 @@ binascii_b2a_base64(PyObject *self, PyObject *args) if (_PyBytes_Resize(&rv, (ascii_data - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_DECREF(rv); - rv = NULL; + Py_CLEAR(rv); } - PyBuffer_Release(&pbuf); return rv; } -PyDoc_STRVAR(doc_a2b_hqx, "ascii -> bin, done. Decode .hqx coding"); +/*[clinic input] +binascii.a2b_hqx + + data: ascii_buffer + / + +Decode .hqx coding. +[clinic start generated code]*/ static PyObject * -binascii_a2b_hqx(PyObject *self, PyObject *args) +binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=60bcdbbd28b105cd input=0d914c680e0eed55]*/ { - Py_buffer pascii; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -584,25 +612,19 @@ binascii_a2b_hqx(PyObject *self, PyObject *args) Py_ssize_t len; int done = 0; - if ( !PyArg_ParseTuple(args, "O&:a2b_hqx", ascii_buffer_converter, &pascii) ) - return NULL; - ascii_data = pascii.buf; - len = pascii.len; + ascii_data = data->buf; + len = data->len; assert(len >= 0); - if (len > PY_SSIZE_T_MAX - 2) { - PyBuffer_Release(&pascii); + if (len > PY_SSIZE_T_MAX - 2) return PyErr_NoMemory(); - } /* 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=PyBytes_FromStringAndSize(NULL, len+2)) == NULL ) { - PyBuffer_Release(&pascii); + if ( (rv=PyBytes_FromStringAndSize(NULL, len+2)) == NULL ) return NULL; - } bin_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; len > 0 ; len--, ascii_data++ ) { @@ -612,7 +634,6 @@ binascii_a2b_hqx(PyObject *self, PyObject *args) continue; if ( this_ch == FAIL ) { PyErr_SetString(Error, "Illegal char"); - PyBuffer_Release(&pascii); Py_DECREF(rv); return NULL; } @@ -635,55 +656,53 @@ binascii_a2b_hqx(PyObject *self, PyObject *args) if ( leftbits && !done ) { PyErr_SetString(Incomplete, "String has incomplete number of bytes"); - PyBuffer_Release(&pascii); Py_DECREF(rv); return NULL; } if (_PyBytes_Resize(&rv, (bin_data - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_DECREF(rv); - rv = NULL; + Py_CLEAR(rv); } if (rv) { PyObject *rrv = Py_BuildValue("Oi", rv, done); - PyBuffer_Release(&pascii); Py_DECREF(rv); return rrv; } - PyBuffer_Release(&pascii); return NULL; } -PyDoc_STRVAR(doc_rlecode_hqx, "Binhex RLE-code binary data"); + +/*[clinic input] +binascii.rlecode_hqx + + data: Py_buffer + / + +Binhex RLE-code binary data. +[clinic start generated code]*/ static PyObject * -binascii_rlecode_hqx(PyObject *self, PyObject *args) +binascii_rlecode_hqx_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=0905da344dbf0648 input=e1f1712447a82b09]*/ { - Py_buffer pbuf; unsigned char *in_data, *out_data; PyObject *rv; unsigned char ch; Py_ssize_t in, inend, len; - if ( !PyArg_ParseTuple(args, "y*:rlecode_hqx", &pbuf) ) - return NULL; - in_data = pbuf.buf; - len = pbuf.len; + in_data = data->buf; + len = data->len; assert(len >= 0); - if (len > PY_SSIZE_T_MAX / 2 - 2) { - PyBuffer_Release(&pbuf); + if (len > PY_SSIZE_T_MAX / 2 - 2) return PyErr_NoMemory(); - } /* Worst case: output is twice as big as input (fixed later) */ - if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) { - PyBuffer_Release(&pbuf); + if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) return NULL; - } out_data = (unsigned char *)PyBytes_AS_STRING(rv); for( in=0; in<len; in++) { @@ -713,19 +732,25 @@ binascii_rlecode_hqx(PyObject *self, PyObject *args) if (_PyBytes_Resize(&rv, (out_data - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_DECREF(rv); - rv = NULL; + Py_CLEAR(rv); } - PyBuffer_Release(&pbuf); return rv; } -PyDoc_STRVAR(doc_b2a_hqx, "Encode .hqx data"); + +/*[clinic input] +binascii.b2a_hqx + + data: Py_buffer + / + +Encode .hqx data. +[clinic start generated code]*/ static PyObject * -binascii_b2a_hqx(PyObject *self, PyObject *args) +binascii_b2a_hqx_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=5a987810d5e3cdbb input=9596ebe019fe12ba]*/ { - Py_buffer pbin; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -733,23 +758,17 @@ binascii_b2a_hqx(PyObject *self, PyObject *args) PyObject *rv; Py_ssize_t len; - if ( !PyArg_ParseTuple(args, "y*:b2a_hqx", &pbin) ) - return NULL; - bin_data = pbin.buf; - len = pbin.len; + bin_data = data->buf; + len = data->len; assert(len >= 0); - if (len > PY_SSIZE_T_MAX / 2 - 2) { - PyBuffer_Release(&pbin); + if (len > PY_SSIZE_T_MAX / 2 - 2) return PyErr_NoMemory(); - } /* Allocate a buffer that is at least large enough */ - if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) { - PyBuffer_Release(&pbin); + if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) return NULL; - } ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; len > 0 ; len--, bin_data++ ) { @@ -770,47 +789,45 @@ binascii_b2a_hqx(PyObject *self, PyObject *args) if (_PyBytes_Resize(&rv, (ascii_data - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_DECREF(rv); - rv = NULL; + Py_CLEAR(rv); } - PyBuffer_Release(&pbin); return rv; } -PyDoc_STRVAR(doc_rledecode_hqx, "Decode hexbin RLE-coded string"); + +/*[clinic input] +binascii.rledecode_hqx + + data: Py_buffer + / + +Decode hexbin RLE-coded string. +[clinic start generated code]*/ static PyObject * -binascii_rledecode_hqx(PyObject *self, PyObject *args) +binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=f7afd89b789946ab input=54cdd49fc014402c]*/ { - Py_buffer pin; unsigned char *in_data, *out_data; unsigned char in_byte, in_repeat; PyObject *rv; Py_ssize_t in_len, out_len, out_len_left; - if ( !PyArg_ParseTuple(args, "y*:rledecode_hqx", &pin) ) - return NULL; - in_data = pin.buf; - in_len = pin.len; + in_data = data->buf; + in_len = data->len; assert(in_len >= 0); /* Empty string is a special case */ - if ( in_len == 0 ) { - PyBuffer_Release(&pin); + if ( in_len == 0 ) return PyBytes_FromStringAndSize("", 0); - } - else if (in_len > PY_SSIZE_T_MAX / 2) { - PyBuffer_Release(&pin); + else if (in_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); - } /* Allocate a buffer of reasonable size. Resized when needed */ out_len = in_len*2; - if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL ) { - PyBuffer_Release(&pin); + if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL ) return NULL; - } out_len_left = out_len; out_data = (unsigned char *)PyBytes_AS_STRING(rv); @@ -823,7 +840,6 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) if ( --in_len < 0 ) { \ PyErr_SetString(Incomplete, ""); \ Py_DECREF(rv); \ - PyBuffer_Release(&pin); \ return NULL; \ } \ b = *in_data++; \ @@ -834,7 +850,7 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) if ( --out_len_left < 0 ) { \ if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \ if (_PyBytes_Resize(&rv, 2*out_len) < 0) \ - { Py_DECREF(rv); PyBuffer_Release(&pin); return NULL; } \ + { Py_XDECREF(rv); return NULL; } \ out_data = (unsigned char *)PyBytes_AS_STRING(rv) \ + out_len; \ out_len_left = out_len-1; \ @@ -856,7 +872,6 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) ** of the string only). This is a programmer error. */ PyErr_SetString(Error, "Orphaned RLE code at start"); - PyBuffer_Release(&pin); Py_DECREF(rv); return NULL; } @@ -887,60 +902,41 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) if (_PyBytes_Resize(&rv, (out_data - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_DECREF(rv); - rv = NULL; + Py_CLEAR(rv); } - PyBuffer_Release(&pin); return rv; } -PyDoc_STRVAR(doc_crc_hqx, -"(data, oldcrc) -> newcrc. Compute hqx CRC incrementally"); -static PyObject * -binascii_crc_hqx(PyObject *self, PyObject *args) +/*[clinic input] +binascii.crc_hqx -> unsigned_int + + data: Py_buffer + crc: unsigned_int(bitwise=True) + / + +Compute hqx CRC incrementally. +[clinic start generated code]*/ + +static unsigned int +binascii_crc_hqx_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc) +/*[clinic end generated code: output=167c2dac62625717 input=add8c53712ccceda]*/ { - Py_buffer pin; unsigned char *bin_data; - unsigned int crc; Py_ssize_t len; - if ( !PyArg_ParseTuple(args, "y*i:crc_hqx", &pin, &crc) ) - return NULL; - bin_data = pin.buf; - len = pin.len; + crc &= 0xffff; + bin_data = data->buf; + len = data->len; while(len-- > 0) { - crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++]; + crc = ((crc<<8)&0xff00) ^ crctab_hqx[(crc>>8)^*bin_data++]; } - PyBuffer_Release(&pin); - return Py_BuildValue("i", crc); + return crc; } -PyDoc_STRVAR(doc_crc32, -"(data, oldcrc = 0) -> newcrc. Compute CRC-32 incrementally"); - -#ifdef USE_ZLIB_CRC32 -/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */ -static PyObject * -binascii_crc32(PyObject *self, PyObject *args) -{ - unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */ - Py_buffer pbuf; - Byte *buf; - Py_ssize_t len; - int signed_val; - - if (!PyArg_ParseTuple(args, "y*|I:crc32", &pbuf, &crc32val)) - return NULL; - buf = (Byte*)pbuf.buf; - len = pbuf.len; - signed_val = crc32(crc32val, buf, len); - PyBuffer_Release(&pbuf); - return PyLong_FromUnsignedLong(signed_val & 0xffffffffU); -} -#else /* USE_ZLIB_CRC32 */ +#ifndef USE_ZLIB_CRC32 /* Crc - 32 BIT ANSI X3.66 CRC checksum files Also known as: ISO 3307 **********************************************************************| @@ -1058,20 +1054,42 @@ static unsigned int crc_32_tab[256] = { 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU }; +#endif /* USE_ZLIB_CRC32 */ -static PyObject * -binascii_crc32(PyObject *self, PyObject *args) +/*[clinic input] +binascii.crc32 -> unsigned_int + + data: Py_buffer + crc: unsigned_int(bitwise=True) = 0 + / + +Compute CRC-32 incrementally. +[clinic start generated code]*/ + +static unsigned int +binascii_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc) +/*[clinic end generated code: output=620a961643393c4f input=bbe340bc99d25aa8]*/ + +#ifdef USE_ZLIB_CRC32 +/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */ +{ + Byte *buf; + Py_ssize_t len; + int signed_val; + + buf = (Byte*)data->buf; + len = data->len; + signed_val = crc32(crc, buf, len); + return (unsigned int)signed_val & 0xffffffffU; +} +#else /* USE_ZLIB_CRC32 */ { /* By Jim Ahlstrom; All rights transferred to CNRI */ - Py_buffer pbin; unsigned char *bin_data; - unsigned int crc = 0; /* initial value of CRC */ Py_ssize_t len; unsigned int result; - if ( !PyArg_ParseTuple(args, "y*|I:crc32", &pbin, &crc) ) - return NULL; - bin_data = pbin.buf; - len = pbin.len; + bin_data = data->buf; + len = data->len; crc = ~ crc; while (len-- > 0) { @@ -1080,38 +1098,42 @@ binascii_crc32(PyObject *self, PyObject *args) } result = (crc ^ 0xFFFFFFFF); - PyBuffer_Release(&pbin); - return PyLong_FromUnsignedLong(result & 0xffffffff); + return result & 0xffffffff; } #endif /* USE_ZLIB_CRC32 */ +/*[clinic input] +binascii.b2a_hex + + data: Py_buffer + / + +Hexadecimal representation of binary data. + +The return value is a bytes object. This function is also +available as "hexlify()". +[clinic start generated code]*/ static PyObject * -binascii_hexlify(PyObject *self, PyObject *args) +binascii_b2a_hex_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=179318922c2f8fda input=96423cfa299ff3b1]*/ { - Py_buffer parg; char* argbuf; Py_ssize_t arglen; PyObject *retval; char* retbuf; Py_ssize_t i, j; - if (!PyArg_ParseTuple(args, "y*:b2a_hex", &parg)) - return NULL; - argbuf = parg.buf; - arglen = parg.len; + argbuf = data->buf; + arglen = data->len; assert(arglen >= 0); - if (arglen > PY_SSIZE_T_MAX / 2) { - PyBuffer_Release(&parg); + if (arglen > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); - } retval = PyBytes_FromStringAndSize(NULL, arglen*2); - if (!retval) { - PyBuffer_Release(&parg); + if (!retval) return NULL; - } retbuf = PyBytes_AS_STRING(retval); /* make hex version of string, taken from shamodule.c */ @@ -1122,16 +1144,23 @@ binascii_hexlify(PyObject *self, PyObject *args) c = argbuf[i] & 0xf; retbuf[j++] = Py_hexdigits[c]; } - PyBuffer_Release(&parg); return retval; } -PyDoc_STRVAR(doc_hexlify, -"b2a_hex(data) -> s; Hexadecimal representation of binary data.\n\ -\n\ -The return value is a bytes object. This function is also\n\ -available as \"hexlify()\"."); +/*[clinic input] +binascii.hexlify = binascii.b2a_hex +Hexadecimal representation of binary data. + +The return value is a bytes object. +[clinic start generated code]*/ + +static PyObject * +binascii_hexlify_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=6098440091fb61dc input=2e3afae7f083f061]*/ +{ + return binascii_b2a_hex_impl(module, data); +} static int to_int(int c) @@ -1148,20 +1177,30 @@ to_int(int c) } +/*[clinic input] +binascii.a2b_hex + + hexstr: ascii_buffer + / + +Binary data of hexadecimal representation. + +hexstr must contain an even number of hex digits (upper or lower case). +This function is also available as "unhexlify()". +[clinic start generated code]*/ + static PyObject * -binascii_unhexlify(PyObject *self, PyObject *args) +binascii_a2b_hex_impl(PyModuleDef *module, Py_buffer *hexstr) +/*[clinic end generated code: output=d61da452b5c6d290 input=9e1e7f2f94db24fd]*/ { - Py_buffer parg; char* argbuf; Py_ssize_t arglen; PyObject *retval; char* retbuf; Py_ssize_t i, j; - if (!PyArg_ParseTuple(args, "O&:a2b_hex", ascii_buffer_converter, &parg)) - return NULL; - argbuf = parg.buf; - arglen = parg.len; + argbuf = hexstr->buf; + arglen = hexstr->len; assert(arglen >= 0); @@ -1170,16 +1209,13 @@ binascii_unhexlify(PyObject *self, PyObject *args) * raise an exception. */ if (arglen % 2) { - PyBuffer_Release(&parg); PyErr_SetString(Error, "Odd-length string"); return NULL; } retval = PyBytes_FromStringAndSize(NULL, (arglen/2)); - if (!retval) { - PyBuffer_Release(&parg); + if (!retval) return NULL; - } retbuf = PyBytes_AS_STRING(retval); for (i=j=0; i < arglen; i += 2) { @@ -1192,20 +1228,27 @@ binascii_unhexlify(PyObject *self, PyObject *args) } retbuf[j++] = (top << 4) + bot; } - PyBuffer_Release(&parg); return retval; finally: - PyBuffer_Release(&parg); Py_DECREF(retval); return NULL; } -PyDoc_STRVAR(doc_unhexlify, -"a2b_hex(hexstr) -> s; Binary data of hexadecimal representation.\n\ -\n\ -hexstr must contain an even number of hex digits (upper or lower case).\n\ -This function is also available as \"unhexlify()\""); +/*[clinic input] +binascii.unhexlify = binascii.a2b_hex + +Binary data of hexadecimal representation. + +hexstr must contain an even number of hex digits (upper or lower case). +[clinic start generated code]*/ + +static PyObject * +binascii_unhexlify_impl(PyModuleDef *module, Py_buffer *hexstr) +/*[clinic end generated code: output=17cec7544499803e input=dd8c012725f462da]*/ +{ + return binascii_a2b_hex_impl(module, hexstr); +} static int table_hex[128] = { -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, @@ -1222,25 +1265,28 @@ static int table_hex[128] = { #define MAXLINESIZE 76 -PyDoc_STRVAR(doc_a2b_qp, "Decode a string of qp-encoded data"); -static PyObject* -binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) +/*[clinic input] +binascii.a2b_qp + + data: ascii_buffer + header: int(c_default="0") = False + +Decode a string of qp-encoded data. +[clinic start generated code]*/ + +static PyObject * +binascii_a2b_qp_impl(PyModuleDef *module, Py_buffer *data, int header) +/*[clinic end generated code: output=a44ef88270352114 input=5187a0d3d8e54f3b]*/ { Py_ssize_t in, out; char ch; - Py_buffer pdata; - unsigned char *data, *odata; + unsigned char *ascii_data, *odata; Py_ssize_t datalen = 0; PyObject *rv; - static char *kwlist[] = {"data", "header", NULL}; - int header = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i:a2b_qp", kwlist, - ascii_buffer_converter, &pdata, &header)) - return NULL; - data = pdata.buf; - datalen = pdata.len; + ascii_data = data->buf; + datalen = data->len; /* We allocate the output same size as input, this is overkill. * The previous implementation used calloc() so we'll zero out the @@ -1248,7 +1294,6 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) */ odata = (unsigned char *) PyMem_Malloc(datalen); if (odata == NULL) { - PyBuffer_Release(&pdata); PyErr_NoMemory(); return NULL; } @@ -1256,31 +1301,31 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) in = out = 0; while (in < datalen) { - if (data[in] == '=') { + if (ascii_data[in] == '=') { in++; if (in >= datalen) break; /* Soft line breaks */ - if ((data[in] == '\n') || (data[in] == '\r')) { - if (data[in] != '\n') { - while (in < datalen && data[in] != '\n') in++; + if ((ascii_data[in] == '\n') || (ascii_data[in] == '\r')) { + if (ascii_data[in] != '\n') { + while (in < datalen && ascii_data[in] != '\n') in++; } if (in < datalen) in++; } - else if (data[in] == '=') { + else if (ascii_data[in] == '=') { /* broken case from broken python qp */ odata[out++] = '='; in++; } - else if (((data[in] >= 'A' && data[in] <= 'F') || - (data[in] >= 'a' && data[in] <= 'f') || - (data[in] >= '0' && data[in] <= '9')) && - ((data[in+1] >= 'A' && data[in+1] <= 'F') || - (data[in+1] >= 'a' && data[in+1] <= 'f') || - (data[in+1] >= '0' && data[in+1] <= '9'))) { + else if (((ascii_data[in] >= 'A' && ascii_data[in] <= 'F') || + (ascii_data[in] >= 'a' && ascii_data[in] <= 'f') || + (ascii_data[in] >= '0' && ascii_data[in] <= '9')) && + ((ascii_data[in+1] >= 'A' && ascii_data[in+1] <= 'F') || + (ascii_data[in+1] >= 'a' && ascii_data[in+1] <= 'f') || + (ascii_data[in+1] >= '0' && ascii_data[in+1] <= '9'))) { /* hexval */ - ch = hexval(data[in]) << 4; + ch = hexval(ascii_data[in]) << 4; in++; - ch |= hexval(data[in]); + ch |= hexval(ascii_data[in]); in++; odata[out++] = ch; } @@ -1288,22 +1333,20 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) odata[out++] = '='; } } - else if (header && data[in] == '_') { + else if (header && ascii_data[in] == '_') { odata[out++] = ' '; in++; } else { - odata[out] = data[in]; + odata[out] = ascii_data[in]; in++; out++; } } if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { - PyBuffer_Release(&pdata); PyMem_Free(odata); return NULL; } - PyBuffer_Release(&pdata); PyMem_Free(odata); return rv; } @@ -1319,63 +1362,63 @@ to_hex (unsigned char ch, unsigned char *s) return 0; } -PyDoc_STRVAR(doc_b2a_qp, -"b2a_qp(data, quotetabs=0, istext=1, header=0) -> s; \n\ - Encode a string using quoted-printable encoding. \n\ -\n\ -On encoding, when istext is set, newlines are not encoded, and white \n\ -space at end of lines is. When istext is not set, \\r and \\n (CR/LF) are \n\ -both encoded. When quotetabs is set, space and tabs are encoded."); - /* XXX: This is ridiculously complicated to be backward compatible * (mostly) with the quopri module. It doesn't re-create the quopri * module bug where text ending in CRLF has the CR encoded */ -static PyObject* -binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) + +/*[clinic input] +binascii.b2a_qp + + data: Py_buffer + quotetabs: int(c_default="0") = False + istext: int(c_default="1") = True + header: int(c_default="0") = False + +Encode a string using quoted-printable encoding. + +On encoding, when istext is set, newlines are not encoded, and white +space at end of lines is. When istext is not set, \r and \n (CR/LF) +are both encoded. When quotetabs is set, space and tabs are encoded. +[clinic start generated code]*/ + +static PyObject * +binascii_b2a_qp_impl(PyModuleDef *module, Py_buffer *data, int quotetabs, int istext, int header) +/*[clinic end generated code: output=ff2991ba640fff3e input=7f2a9aaa008e92b2]*/ { Py_ssize_t in, out; - Py_buffer pdata; - unsigned char *data, *odata; + unsigned char *databuf, *odata; Py_ssize_t datalen = 0, odatalen = 0; PyObject *rv; unsigned int linelen = 0; - static char *kwlist[] = {"data", "quotetabs", "istext", - "header", NULL}; - int istext = 1; - int quotetabs = 0; - int header = 0; unsigned char ch; int crlf = 0; unsigned char *p; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|iii", kwlist, &pdata, - "etabs, &istext, &header)) - return NULL; - data = pdata.buf; - datalen = pdata.len; + databuf = data->buf; + datalen = data->len; /* See if this string is using CRLF line ends */ /* XXX: this function has the side effect of converting all of * the end of lines to be the same depending on this detection * here */ - p = (unsigned char *) memchr(data, '\n', datalen); - if ((p != NULL) && (p > data) && (*(p-1) == '\r')) + p = (unsigned char *) memchr(databuf, '\n', datalen); + if ((p != NULL) && (p > databuf) && (*(p-1) == '\r')) crlf = 1; /* First, scan to see how many characters need to be encoded */ in = 0; while (in < datalen) { Py_ssize_t delta = 0; - if ((data[in] > 126) || - (data[in] == '=') || - (header && data[in] == '_') || - ((data[in] == '.') && (linelen == 0) && - (data[in+1] == '\n' || data[in+1] == '\r' || data[in+1] == 0)) || - (!istext && ((data[in] == '\r') || (data[in] == '\n'))) || - ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) || - ((data[in] < 33) && - (data[in] != '\r') && (data[in] != '\n') && - (quotetabs || ((data[in] != '\t') && (data[in] != ' '))))) + if ((databuf[in] > 126) || + (databuf[in] == '=') || + (header && databuf[in] == '_') || + ((databuf[in] == '.') && (linelen == 0) && + (databuf[in+1] == '\n' || databuf[in+1] == '\r' || databuf[in+1] == 0)) || + (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) || + ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) || + ((databuf[in] < 33) && + (databuf[in] != '\r') && (databuf[in] != '\n') && + (quotetabs || ((databuf[in] != '\t') && (databuf[in] != ' '))))) { if ((linelen + 3) >= MAXLINESIZE) { linelen = 0; @@ -1390,26 +1433,26 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) } else { if (istext && - ((data[in] == '\n') || - ((in+1 < datalen) && (data[in] == '\r') && - (data[in+1] == '\n')))) + ((databuf[in] == '\n') || + ((in+1 < datalen) && (databuf[in] == '\r') && + (databuf[in+1] == '\n')))) { linelen = 0; /* Protect against whitespace on end of line */ - if (in && ((data[in-1] == ' ') || (data[in-1] == '\t'))) + if (in && ((databuf[in-1] == ' ') || (databuf[in-1] == '\t'))) delta += 2; if (crlf) delta += 2; else delta += 1; - if (data[in] == '\r') + if (databuf[in] == '\r') in += 2; else in++; } else { if ((in + 1 != datalen) && - (data[in+1] != '\n') && + (databuf[in+1] != '\n') && (linelen + 1) >= MAXLINESIZE) { linelen = 0; if (crlf) @@ -1423,7 +1466,6 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) } } if (PY_SSIZE_T_MAX - delta < odatalen) { - PyBuffer_Release(&pdata); PyErr_NoMemory(); return NULL; } @@ -1436,7 +1478,6 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) */ odata = (unsigned char *) PyMem_Malloc(odatalen); if (odata == NULL) { - PyBuffer_Release(&pdata); PyErr_NoMemory(); return NULL; } @@ -1444,17 +1485,17 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) in = out = linelen = 0; while (in < datalen) { - if ((data[in] > 126) || - (data[in] == '=') || - (header && data[in] == '_') || - ((data[in] == '.') && (linelen == 0) && - (data[in+1] == '\n' || data[in+1] == '\r' || data[in+1] == 0)) || - (!istext && ((data[in] == '\r') || (data[in] == '\n'))) || - ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) || - ((data[in] < 33) && - (data[in] != '\r') && (data[in] != '\n') && + if ((databuf[in] > 126) || + (databuf[in] == '=') || + (header && databuf[in] == '_') || + ((databuf[in] == '.') && (linelen == 0) && + (databuf[in+1] == '\n' || databuf[in+1] == '\r' || databuf[in+1] == 0)) || + (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) || + ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) || + ((databuf[in] < 33) && + (databuf[in] != '\r') && (databuf[in] != '\n') && (quotetabs || - (!quotetabs && ((data[in] != '\t') && (data[in] != ' ')))))) + (!quotetabs && ((databuf[in] != '\t') && (databuf[in] != ' ')))))) { if ((linelen + 3 )>= MAXLINESIZE) { odata[out++] = '='; @@ -1463,16 +1504,16 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) linelen = 0; } odata[out++] = '='; - to_hex(data[in], &odata[out]); + to_hex(databuf[in], &odata[out]); out += 2; in++; linelen += 3; } else { if (istext && - ((data[in] == '\n') || - ((in+1 < datalen) && (data[in] == '\r') && - (data[in+1] == '\n')))) + ((databuf[in] == '\n') || + ((in+1 < datalen) && (databuf[in] == '\r') && + (databuf[in+1] == '\n')))) { linelen = 0; /* Protect against whitespace on end of line */ @@ -1485,14 +1526,14 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) if (crlf) odata[out++] = '\r'; odata[out++] = '\n'; - if (data[in] == '\r') + if (databuf[in] == '\r') in += 2; else in++; } else { if ((in + 1 != datalen) && - (data[in+1] != '\n') && + (databuf[in+1] != '\n') && (linelen + 1) >= MAXLINESIZE) { odata[out++] = '='; if (crlf) odata[out++] = '\r'; @@ -1500,22 +1541,20 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) linelen = 0; } linelen++; - if (header && data[in] == ' ') { + if (header && databuf[in] == ' ') { odata[out++] = '_'; in++; } else { - odata[out++] = data[in++]; + odata[out++] = databuf[in++]; } } } } if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { - PyBuffer_Release(&pdata); PyMem_Free(odata); return NULL; } - PyBuffer_Release(&pdata); PyMem_Free(odata); return rv; } @@ -1523,25 +1562,22 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) /* List of functions defined in the module */ static struct PyMethodDef binascii_module_methods[] = { - {"a2b_uu", binascii_a2b_uu, METH_VARARGS, doc_a2b_uu}, - {"b2a_uu", binascii_b2a_uu, METH_VARARGS, doc_b2a_uu}, - {"a2b_base64", binascii_a2b_base64, METH_VARARGS, doc_a2b_base64}, - {"b2a_base64", binascii_b2a_base64, METH_VARARGS, doc_b2a_base64}, - {"a2b_hqx", binascii_a2b_hqx, METH_VARARGS, doc_a2b_hqx}, - {"b2a_hqx", binascii_b2a_hqx, METH_VARARGS, doc_b2a_hqx}, - {"b2a_hex", binascii_hexlify, METH_VARARGS, doc_hexlify}, - {"a2b_hex", binascii_unhexlify, METH_VARARGS, doc_unhexlify}, - {"hexlify", binascii_hexlify, METH_VARARGS, doc_hexlify}, - {"unhexlify", binascii_unhexlify, METH_VARARGS, doc_unhexlify}, - {"rlecode_hqx", binascii_rlecode_hqx, METH_VARARGS, doc_rlecode_hqx}, - {"rledecode_hqx", binascii_rledecode_hqx, METH_VARARGS, - doc_rledecode_hqx}, - {"crc_hqx", binascii_crc_hqx, METH_VARARGS, doc_crc_hqx}, - {"crc32", binascii_crc32, METH_VARARGS, doc_crc32}, - {"a2b_qp", (PyCFunction)binascii_a2b_qp, METH_VARARGS | METH_KEYWORDS, - doc_a2b_qp}, - {"b2a_qp", (PyCFunction)binascii_b2a_qp, METH_VARARGS | METH_KEYWORDS, - doc_b2a_qp}, + BINASCII_A2B_UU_METHODDEF + BINASCII_B2A_UU_METHODDEF + BINASCII_A2B_BASE64_METHODDEF + BINASCII_B2A_BASE64_METHODDEF + BINASCII_A2B_HQX_METHODDEF + BINASCII_B2A_HQX_METHODDEF + BINASCII_A2B_HEX_METHODDEF + BINASCII_B2A_HEX_METHODDEF + BINASCII_HEXLIFY_METHODDEF + BINASCII_UNHEXLIFY_METHODDEF + BINASCII_RLECODE_HQX_METHODDEF + BINASCII_RLEDECODE_HQX_METHODDEF + BINASCII_CRC_HQX_METHODDEF + BINASCII_CRC32_METHODDEF + BINASCII_A2B_QP_METHODDEF + BINASCII_B2A_QP_METHODDEF {NULL, NULL} /* sentinel */ }; |