Kaydet (Commit) 3ffd913d authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka

Issue #20151: The binascii module now uses Argument Clinic.

üst e4e7199c
...@@ -183,6 +183,22 @@ static unsigned short crctab_hqx[256] = { ...@@ -183,6 +183,22 @@ static unsigned short crctab_hqx[256] = {
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
}; };
/*[clinic input]
output preset file
module binascii
[clinic start generated code]*/
/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
/*[python input]
class ascii_buffer_converter(CConverter):
type = 'Py_buffer'
converter = 'ascii_buffer_converter'
impl_by_reference = True
[python start generated code]*/
/*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
static int static int
ascii_buffer_converter(PyObject *arg, Py_buffer *buf) ascii_buffer_converter(PyObject *arg, Py_buffer *buf)
{ {
...@@ -220,13 +236,21 @@ ascii_buffer_converter(PyObject *arg, Py_buffer *buf) ...@@ -220,13 +236,21 @@ ascii_buffer_converter(PyObject *arg, Py_buffer *buf)
return Py_CLEANUP_SUPPORTED; return Py_CLEANUP_SUPPORTED;
} }
#include "binascii.clinic.c"
PyDoc_STRVAR(doc_a2b_uu, "(ascii) -> bin. Decode a line of uuencoded data"); /*[clinic input]
binascii.a2b_uu
ascii: ascii_buffer
/
Decode a line of uuencoded data.
[clinic start generated code]*/
static PyObject * static PyObject *
binascii_a2b_uu(PyObject *self, PyObject *args) binascii_a2b_uu_impl(PyModuleDef *module, Py_buffer *ascii)
/*[clinic end generated code: checksum=3252d1dbb682979eee03fb2c0c48a4d98a229df4]*/
{ {
Py_buffer pascii;
unsigned char *ascii_data, *bin_data; unsigned char *ascii_data, *bin_data;
int leftbits = 0; int leftbits = 0;
unsigned char this_ch; unsigned char this_ch;
...@@ -234,10 +258,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args) ...@@ -234,10 +258,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
PyObject *rv; PyObject *rv;
Py_ssize_t ascii_len, bin_len; Py_ssize_t ascii_len, bin_len;
if ( !PyArg_ParseTuple(args, "O&:a2b_uu", ascii_buffer_converter, &pascii) ) ascii_data = ascii->buf;
return NULL; ascii_len = ascii->len;
ascii_data = pascii.buf;
ascii_len = pascii.len;
assert(ascii_len >= 0); assert(ascii_len >= 0);
...@@ -246,10 +268,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args) ...@@ -246,10 +268,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
ascii_len--; ascii_len--;
/* Allocate the buffer */ /* Allocate the buffer */
if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) { if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL )
PyBuffer_Release(&pascii);
return NULL; return NULL;
}
bin_data = (unsigned char *)PyBytes_AS_STRING(rv); bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) { for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) {
...@@ -269,7 +289,6 @@ binascii_a2b_uu(PyObject *self, PyObject *args) ...@@ -269,7 +289,6 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
*/ */
if ( this_ch < ' ' || this_ch > (' ' + 64)) { if ( this_ch < ' ' || this_ch > (' ' + 64)) {
PyErr_SetString(Error, "Illegal char"); PyErr_SetString(Error, "Illegal char");
PyBuffer_Release(&pascii);
Py_DECREF(rv); Py_DECREF(rv);
return NULL; return NULL;
} }
...@@ -298,21 +317,26 @@ binascii_a2b_uu(PyObject *self, PyObject *args) ...@@ -298,21 +317,26 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
if ( this_ch != ' ' && this_ch != ' '+64 && if ( this_ch != ' ' && this_ch != ' '+64 &&
this_ch != '\n' && this_ch != '\r' ) { this_ch != '\n' && this_ch != '\r' ) {
PyErr_SetString(Error, "Trailing garbage"); PyErr_SetString(Error, "Trailing garbage");
PyBuffer_Release(&pascii);
Py_DECREF(rv); Py_DECREF(rv);
return NULL; return NULL;
} }
} }
PyBuffer_Release(&pascii);
return rv; 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 * static PyObject *
binascii_b2a_uu(PyObject *self, PyObject *args) binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data)
/*[clinic end generated code: checksum=181021b69bb9a4149fffa98aa3ed57b59ffa38cb]*/
{ {
Py_buffer pbin;
unsigned char *ascii_data, *bin_data; unsigned char *ascii_data, *bin_data;
int leftbits = 0; int leftbits = 0;
unsigned char this_ch; unsigned char this_ch;
...@@ -320,22 +344,17 @@ binascii_b2a_uu(PyObject *self, PyObject *args) ...@@ -320,22 +344,17 @@ binascii_b2a_uu(PyObject *self, PyObject *args)
PyObject *rv; PyObject *rv;
Py_ssize_t bin_len; Py_ssize_t bin_len;
if ( !PyArg_ParseTuple(args, "y*:b2a_uu", &pbin) ) bin_data = data->buf;
return NULL; bin_len = data->len;
bin_data = pbin.buf;
bin_len = pbin.len;
if ( bin_len > 45 ) { if ( bin_len > 45 ) {
/* The 45 is a limit that appears in all uuencode's */ /* The 45 is a limit that appears in all uuencode's */
PyErr_SetString(Error, "At most 45 bytes at once"); PyErr_SetString(Error, "At most 45 bytes at once");
PyBuffer_Release(&pbin);
return NULL; return NULL;
} }
/* We're lazy and allocate to much (fixed up later) */ /* We're lazy and allocate to much (fixed up later) */
if ( (rv=PyBytes_FromStringAndSize(NULL, 2 + (bin_len+2)/3*4)) == NULL ) { if ( (rv=PyBytes_FromStringAndSize(NULL, 2 + (bin_len+2)/3*4)) == NULL )
PyBuffer_Release(&pbin);
return NULL; return NULL;
}
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
/* Store the length */ /* Store the length */
...@@ -363,7 +382,6 @@ binascii_b2a_uu(PyObject *self, PyObject *args) ...@@ -363,7 +382,6 @@ binascii_b2a_uu(PyObject *self, PyObject *args)
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) { (unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
Py_CLEAR(rv); Py_CLEAR(rv);
} }
PyBuffer_Release(&pbin);
return rv; return rv;
} }
...@@ -393,12 +411,19 @@ binascii_find_valid(unsigned char *s, Py_ssize_t slen, int num) ...@@ -393,12 +411,19 @@ binascii_find_valid(unsigned char *s, Py_ssize_t slen, int num)
return ret; return ret;
} }
PyDoc_STRVAR(doc_a2b_base64, "(ascii) -> bin. Decode a line of base64 data"); /*[clinic input]
binascii.a2b_base64
ascii: ascii_buffer
/
Decode a line of base64 data.
[clinic start generated code]*/
static PyObject * static PyObject *
binascii_a2b_base64(PyObject *self, PyObject *args) binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *ascii)
/*[clinic end generated code: checksum=73c265f87068c1f3e4bc01834ae6ac5a974143b4]*/
{ {
Py_buffer pascii;
unsigned char *ascii_data, *bin_data; unsigned char *ascii_data, *bin_data;
int leftbits = 0; int leftbits = 0;
unsigned char this_ch; unsigned char this_ch;
...@@ -407,25 +432,19 @@ binascii_a2b_base64(PyObject *self, PyObject *args) ...@@ -407,25 +432,19 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
Py_ssize_t ascii_len, bin_len; Py_ssize_t ascii_len, bin_len;
int quad_pos = 0; int quad_pos = 0;
if ( !PyArg_ParseTuple(args, "O&:a2b_base64", ascii_buffer_converter, &pascii) ) ascii_data = ascii->buf;
return NULL; ascii_len = ascii->len;
ascii_data = pascii.buf;
ascii_len = pascii.len;
assert(ascii_len >= 0); assert(ascii_len >= 0);
if (ascii_len > PY_SSIZE_T_MAX - 3) { if (ascii_len > PY_SSIZE_T_MAX - 3)
PyBuffer_Release(&pascii);
return PyErr_NoMemory(); return PyErr_NoMemory();
}
bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */ bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
/* Allocate the buffer */ /* Allocate the buffer */
if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) { if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL )
PyBuffer_Release(&pascii);
return NULL; return NULL;
}
bin_data = (unsigned char *)PyBytes_AS_STRING(rv); bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
bin_len = 0; bin_len = 0;
...@@ -478,7 +497,6 @@ binascii_a2b_base64(PyObject *self, PyObject *args) ...@@ -478,7 +497,6 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
} }
if (leftbits != 0) { if (leftbits != 0) {
PyBuffer_Release(&pascii);
PyErr_SetString(Error, "Incorrect padding"); PyErr_SetString(Error, "Incorrect padding");
Py_DECREF(rv); Py_DECREF(rv);
return NULL; return NULL;
...@@ -497,16 +515,23 @@ binascii_a2b_base64(PyObject *self, PyObject *args) ...@@ -497,16 +515,23 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
Py_DECREF(rv); Py_DECREF(rv);
rv = PyBytes_FromStringAndSize("", 0); rv = PyBytes_FromStringAndSize("", 0);
} }
PyBuffer_Release(&pascii);
return rv; 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 * static PyObject *
binascii_b2a_base64(PyObject *self, PyObject *args) binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data)
/*[clinic end generated code: checksum=3cd61fbee2913285e253bc5415c9d052b0c5dd96]*/
{ {
Py_buffer pbuf;
unsigned char *ascii_data, *bin_data; unsigned char *ascii_data, *bin_data;
int leftbits = 0; int leftbits = 0;
unsigned char this_ch; unsigned char this_ch;
...@@ -514,26 +539,21 @@ binascii_b2a_base64(PyObject *self, PyObject *args) ...@@ -514,26 +539,21 @@ binascii_b2a_base64(PyObject *self, PyObject *args)
PyObject *rv; PyObject *rv;
Py_ssize_t bin_len; Py_ssize_t bin_len;
if ( !PyArg_ParseTuple(args, "y*:b2a_base64", &pbuf) ) bin_data = data->buf;
return NULL; bin_len = data->len;
bin_data = pbuf.buf;
bin_len = pbuf.len;
assert(bin_len >= 0); assert(bin_len >= 0);
if ( bin_len > BASE64_MAXBIN ) { if ( bin_len > BASE64_MAXBIN ) {
PyErr_SetString(Error, "Too much data for base64 line"); PyErr_SetString(Error, "Too much data for base64 line");
PyBuffer_Release(&pbuf);
return NULL; return NULL;
} }
/* We're lazy and allocate too much (fixed up later). /* We're lazy and allocate too much (fixed up later).
"+3" leaves room for up to two pad characters and a trailing "+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). */ newline. Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */
if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL ) { if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL )
PyBuffer_Release(&pbuf);
return NULL; return NULL;
}
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( ; bin_len > 0 ; bin_len--, bin_data++ ) { for( ; bin_len > 0 ; bin_len--, bin_data++ ) {
...@@ -563,16 +583,22 @@ binascii_b2a_base64(PyObject *self, PyObject *args) ...@@ -563,16 +583,22 @@ binascii_b2a_base64(PyObject *self, PyObject *args)
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) { (unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
Py_CLEAR(rv); Py_CLEAR(rv);
} }
PyBuffer_Release(&pbuf);
return rv; return rv;
} }
PyDoc_STRVAR(doc_a2b_hqx, "ascii -> bin, done. Decode .hqx coding"); /*[clinic input]
binascii.a2b_hqx
ascii: ascii_buffer
/
Decode .hqx coding.
[clinic start generated code]*/
static PyObject * static PyObject *
binascii_a2b_hqx(PyObject *self, PyObject *args) binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *ascii)
/*[clinic end generated code: checksum=48075dc4017b66f93086386d5b5848f1e6af260c]*/
{ {
Py_buffer pascii;
unsigned char *ascii_data, *bin_data; unsigned char *ascii_data, *bin_data;
int leftbits = 0; int leftbits = 0;
unsigned char this_ch; unsigned char this_ch;
...@@ -581,25 +607,19 @@ binascii_a2b_hqx(PyObject *self, PyObject *args) ...@@ -581,25 +607,19 @@ binascii_a2b_hqx(PyObject *self, PyObject *args)
Py_ssize_t len; Py_ssize_t len;
int done = 0; int done = 0;
if ( !PyArg_ParseTuple(args, "O&:a2b_hqx", ascii_buffer_converter, &pascii) ) ascii_data = ascii->buf;
return NULL; len = ascii->len;
ascii_data = pascii.buf;
len = pascii.len;
assert(len >= 0); assert(len >= 0);
if (len > PY_SSIZE_T_MAX - 2) { if (len > PY_SSIZE_T_MAX - 2)
PyBuffer_Release(&pascii);
return PyErr_NoMemory(); return PyErr_NoMemory();
}
/* Allocate a string that is too big (fixed later) /* Allocate a string that is too big (fixed later)
Add two to the initial length to prevent interning which Add two to the initial length to prevent interning which
would preclude subsequent resizing. */ would preclude subsequent resizing. */
if ( (rv=PyBytes_FromStringAndSize(NULL, len+2)) == NULL ) { if ( (rv=PyBytes_FromStringAndSize(NULL, len+2)) == NULL )
PyBuffer_Release(&pascii);
return NULL; return NULL;
}
bin_data = (unsigned char *)PyBytes_AS_STRING(rv); bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( ; len > 0 ; len--, ascii_data++ ) { for( ; len > 0 ; len--, ascii_data++ ) {
...@@ -609,7 +629,6 @@ binascii_a2b_hqx(PyObject *self, PyObject *args) ...@@ -609,7 +629,6 @@ binascii_a2b_hqx(PyObject *self, PyObject *args)
continue; continue;
if ( this_ch == FAIL ) { if ( this_ch == FAIL ) {
PyErr_SetString(Error, "Illegal char"); PyErr_SetString(Error, "Illegal char");
PyBuffer_Release(&pascii);
Py_DECREF(rv); Py_DECREF(rv);
return NULL; return NULL;
} }
...@@ -632,7 +651,6 @@ binascii_a2b_hqx(PyObject *self, PyObject *args) ...@@ -632,7 +651,6 @@ binascii_a2b_hqx(PyObject *self, PyObject *args)
if ( leftbits && !done ) { if ( leftbits && !done ) {
PyErr_SetString(Incomplete, PyErr_SetString(Incomplete,
"String has incomplete number of bytes"); "String has incomplete number of bytes");
PyBuffer_Release(&pascii);
Py_DECREF(rv); Py_DECREF(rv);
return NULL; return NULL;
} }
...@@ -643,43 +661,43 @@ binascii_a2b_hqx(PyObject *self, PyObject *args) ...@@ -643,43 +661,43 @@ binascii_a2b_hqx(PyObject *self, PyObject *args)
} }
if (rv) { if (rv) {
PyObject *rrv = Py_BuildValue("Oi", rv, done); PyObject *rrv = Py_BuildValue("Oi", rv, done);
PyBuffer_Release(&pascii);
Py_DECREF(rv); Py_DECREF(rv);
return rrv; return rrv;
} }
PyBuffer_Release(&pascii);
return NULL; 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 * static PyObject *
binascii_rlecode_hqx(PyObject *self, PyObject *args) binascii_rlecode_hqx_impl(PyModuleDef *module, Py_buffer *data)
/*[clinic end generated code: checksum=0905da344dbf064855925c3a0fb83ec11ca33e8b]*/
{ {
Py_buffer pbuf;
unsigned char *in_data, *out_data; unsigned char *in_data, *out_data;
PyObject *rv; PyObject *rv;
unsigned char ch; unsigned char ch;
Py_ssize_t in, inend, len; Py_ssize_t in, inend, len;
if ( !PyArg_ParseTuple(args, "y*:rlecode_hqx", &pbuf) ) in_data = data->buf;
return NULL; len = data->len;
in_data = pbuf.buf;
len = pbuf.len;
assert(len >= 0); assert(len >= 0);
if (len > PY_SSIZE_T_MAX / 2 - 2) { if (len > PY_SSIZE_T_MAX / 2 - 2)
PyBuffer_Release(&pbuf);
return PyErr_NoMemory(); return PyErr_NoMemory();
}
/* Worst case: output is twice as big as input (fixed later) */ /* Worst case: output is twice as big as input (fixed later) */
if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) { if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL )
PyBuffer_Release(&pbuf);
return NULL; return NULL;
}
out_data = (unsigned char *)PyBytes_AS_STRING(rv); out_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( in=0; in<len; in++) { for( in=0; in<len; in++) {
...@@ -711,16 +729,23 @@ binascii_rlecode_hqx(PyObject *self, PyObject *args) ...@@ -711,16 +729,23 @@ binascii_rlecode_hqx(PyObject *self, PyObject *args)
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) { (unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
Py_CLEAR(rv); Py_CLEAR(rv);
} }
PyBuffer_Release(&pbuf);
return rv; 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 * static PyObject *
binascii_b2a_hqx(PyObject *self, PyObject *args) binascii_b2a_hqx_impl(PyModuleDef *module, Py_buffer *data)
/*[clinic end generated code: checksum=5a987810d5e3cdbb0eb415eba8907c022342fe15]*/
{ {
Py_buffer pbin;
unsigned char *ascii_data, *bin_data; unsigned char *ascii_data, *bin_data;
int leftbits = 0; int leftbits = 0;
unsigned char this_ch; unsigned char this_ch;
...@@ -728,23 +753,17 @@ binascii_b2a_hqx(PyObject *self, PyObject *args) ...@@ -728,23 +753,17 @@ binascii_b2a_hqx(PyObject *self, PyObject *args)
PyObject *rv; PyObject *rv;
Py_ssize_t len; Py_ssize_t len;
if ( !PyArg_ParseTuple(args, "y*:b2a_hqx", &pbin) ) bin_data = data->buf;
return NULL; len = data->len;
bin_data = pbin.buf;
len = pbin.len;
assert(len >= 0); assert(len >= 0);
if (len > PY_SSIZE_T_MAX / 2 - 2) { if (len > PY_SSIZE_T_MAX / 2 - 2)
PyBuffer_Release(&pbin);
return PyErr_NoMemory(); return PyErr_NoMemory();
}
/* Allocate a buffer that is at least large enough */ /* Allocate a buffer that is at least large enough */
if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) { if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL )
PyBuffer_Release(&pbin);
return NULL; return NULL;
}
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( ; len > 0 ; len--, bin_data++ ) { for( ; len > 0 ; len--, bin_data++ ) {
...@@ -767,44 +786,43 @@ binascii_b2a_hqx(PyObject *self, PyObject *args) ...@@ -767,44 +786,43 @@ binascii_b2a_hqx(PyObject *self, PyObject *args)
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) { (unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
Py_CLEAR(rv); Py_CLEAR(rv);
} }
PyBuffer_Release(&pbin);
return rv; 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 * static PyObject *
binascii_rledecode_hqx(PyObject *self, PyObject *args) binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data)
/*[clinic end generated code: checksum=f7afd89b789946ab50e31d595c695d5cad7e27e3]*/
{ {
Py_buffer pin;
unsigned char *in_data, *out_data; unsigned char *in_data, *out_data;
unsigned char in_byte, in_repeat; unsigned char in_byte, in_repeat;
PyObject *rv; PyObject *rv;
Py_ssize_t in_len, out_len, out_len_left; Py_ssize_t in_len, out_len, out_len_left;
if ( !PyArg_ParseTuple(args, "y*:rledecode_hqx", &pin) ) in_data = data->buf;
return NULL; in_len = data->len;
in_data = pin.buf;
in_len = pin.len;
assert(in_len >= 0); assert(in_len >= 0);
/* Empty string is a special case */ /* Empty string is a special case */
if ( in_len == 0 ) { if ( in_len == 0 )
PyBuffer_Release(&pin);
return PyBytes_FromStringAndSize("", 0); return PyBytes_FromStringAndSize("", 0);
} else if (in_len > PY_SSIZE_T_MAX / 2)
else if (in_len > PY_SSIZE_T_MAX / 2) {
PyBuffer_Release(&pin);
return PyErr_NoMemory(); return PyErr_NoMemory();
}
/* Allocate a buffer of reasonable size. Resized when needed */ /* Allocate a buffer of reasonable size. Resized when needed */
out_len = in_len*2; out_len = in_len*2;
if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL ) { if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL )
PyBuffer_Release(&pin);
return NULL; return NULL;
}
out_len_left = out_len; out_len_left = out_len;
out_data = (unsigned char *)PyBytes_AS_STRING(rv); out_data = (unsigned char *)PyBytes_AS_STRING(rv);
...@@ -817,7 +835,6 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) ...@@ -817,7 +835,6 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
if ( --in_len < 0 ) { \ if ( --in_len < 0 ) { \
PyErr_SetString(Incomplete, ""); \ PyErr_SetString(Incomplete, ""); \
Py_DECREF(rv); \ Py_DECREF(rv); \
PyBuffer_Release(&pin); \
return NULL; \ return NULL; \
} \ } \
b = *in_data++; \ b = *in_data++; \
...@@ -828,7 +845,7 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) ...@@ -828,7 +845,7 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
if ( --out_len_left < 0 ) { \ if ( --out_len_left < 0 ) { \
if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \ if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \
if (_PyBytes_Resize(&rv, 2*out_len) < 0) \ if (_PyBytes_Resize(&rv, 2*out_len) < 0) \
{ Py_XDECREF(rv); PyBuffer_Release(&pin); return NULL; } \ { Py_XDECREF(rv); return NULL; } \
out_data = (unsigned char *)PyBytes_AS_STRING(rv) \ out_data = (unsigned char *)PyBytes_AS_STRING(rv) \
+ out_len; \ + out_len; \
out_len_left = out_len-1; \ out_len_left = out_len-1; \
...@@ -850,7 +867,6 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) ...@@ -850,7 +867,6 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
** of the string only). This is a programmer error. ** of the string only). This is a programmer error.
*/ */
PyErr_SetString(Error, "Orphaned RLE code at start"); PyErr_SetString(Error, "Orphaned RLE code at start");
PyBuffer_Release(&pin);
Py_DECREF(rv); Py_DECREF(rv);
return NULL; return NULL;
} }
...@@ -883,57 +899,39 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) ...@@ -883,57 +899,39 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) { (unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
Py_CLEAR(rv); Py_CLEAR(rv);
} }
PyBuffer_Release(&pin);
return rv; return rv;
} }
PyDoc_STRVAR(doc_crc_hqx,
"(data, oldcrc) -> newcrc. Compute hqx CRC incrementally");
static PyObject * /*[clinic input]
binascii_crc_hqx(PyObject *self, PyObject *args) binascii.crc_hqx -> int
data: Py_buffer
crc: int
/
Compute hqx CRC incrementally.
[clinic start generated code]*/
static int
binascii_crc_hqx_impl(PyModuleDef *module, Py_buffer *data, int crc)
/*[clinic end generated code: checksum=634dac18dfa863d738833b5a0886eca93c034c0c]*/
{ {
Py_buffer pin;
unsigned char *bin_data; unsigned char *bin_data;
unsigned int crc; unsigned int ucrc = (unsigned int)crc;
Py_ssize_t len; Py_ssize_t len;
if ( !PyArg_ParseTuple(args, "y*i:crc_hqx", &pin, &crc) ) bin_data = data->buf;
return NULL; len = data->len;
bin_data = pin.buf;
len = pin.len;
while(len-- > 0) { while(len-- > 0) {
crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++]; ucrc=((ucrc<<8)&0xff00)^crctab_hqx[((ucrc>>8)&0xff)^*bin_data++];
} }
PyBuffer_Release(&pin); return (int)ucrc;
return Py_BuildValue("i", crc);
} }
PyDoc_STRVAR(doc_crc32, #ifndef USE_ZLIB_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 */
/* Crc - 32 BIT ANSI X3.66 CRC checksum files /* Crc - 32 BIT ANSI X3.66 CRC checksum files
Also known as: ISO 3307 Also known as: ISO 3307
**********************************************************************| **********************************************************************|
...@@ -1051,20 +1049,42 @@ static unsigned int crc_32_tab[256] = { ...@@ -1051,20 +1049,42 @@ static unsigned int crc_32_tab[256] = {
0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU,
0x2d02ef8dU 0x2d02ef8dU
}; };
#endif /* USE_ZLIB_CRC32 */
static PyObject * /*[clinic input]
binascii_crc32(PyObject *self, PyObject *args) 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: checksum=620a961643393c4f2a1fb273fda2acb43970c3f5]*/
#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 */ { /* By Jim Ahlstrom; All rights transferred to CNRI */
Py_buffer pbin;
unsigned char *bin_data; unsigned char *bin_data;
unsigned int crc = 0; /* initial value of CRC */
Py_ssize_t len; Py_ssize_t len;
unsigned int result; unsigned int result;
if ( !PyArg_ParseTuple(args, "y*|I:crc32", &pbin, &crc) ) bin_data = data->buf;
return NULL; len = data->len;
bin_data = pbin.buf;
len = pbin.len;
crc = ~ crc; crc = ~ crc;
while (len-- > 0) { while (len-- > 0) {
...@@ -1073,38 +1093,42 @@ binascii_crc32(PyObject *self, PyObject *args) ...@@ -1073,38 +1093,42 @@ binascii_crc32(PyObject *self, PyObject *args)
} }
result = (crc ^ 0xFFFFFFFF); result = (crc ^ 0xFFFFFFFF);
PyBuffer_Release(&pbin); return result & 0xffffffff;
return PyLong_FromUnsignedLong(result & 0xffffffff);
} }
#endif /* USE_ZLIB_CRC32 */ #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 * static PyObject *
binascii_hexlify(PyObject *self, PyObject *args) binascii_b2a_hex_impl(PyModuleDef *module, Py_buffer *data)
/*[clinic end generated code: checksum=179318922c2f8fdaee0d4d3283758aec8e8741a5]*/
{ {
Py_buffer parg;
char* argbuf; char* argbuf;
Py_ssize_t arglen; Py_ssize_t arglen;
PyObject *retval; PyObject *retval;
char* retbuf; char* retbuf;
Py_ssize_t i, j; Py_ssize_t i, j;
if (!PyArg_ParseTuple(args, "y*:b2a_hex", &parg)) argbuf = data->buf;
return NULL; arglen = data->len;
argbuf = parg.buf;
arglen = parg.len;
assert(arglen >= 0); assert(arglen >= 0);
if (arglen > PY_SSIZE_T_MAX / 2) { if (arglen > PY_SSIZE_T_MAX / 2)
PyBuffer_Release(&parg);
return PyErr_NoMemory(); return PyErr_NoMemory();
}
retval = PyBytes_FromStringAndSize(NULL, arglen*2); retval = PyBytes_FromStringAndSize(NULL, arglen*2);
if (!retval) { if (!retval)
PyBuffer_Release(&parg);
return NULL; return NULL;
}
retbuf = PyBytes_AS_STRING(retval); retbuf = PyBytes_AS_STRING(retval);
/* make hex version of string, taken from shamodule.c */ /* make hex version of string, taken from shamodule.c */
...@@ -1115,16 +1139,9 @@ binascii_hexlify(PyObject *self, PyObject *args) ...@@ -1115,16 +1139,9 @@ binascii_hexlify(PyObject *self, PyObject *args)
c = argbuf[i] & 0xf; c = argbuf[i] & 0xf;
retbuf[j++] = Py_hexdigits[c]; retbuf[j++] = Py_hexdigits[c];
} }
PyBuffer_Release(&parg);
return retval; 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()\".");
static int static int
to_int(int c) to_int(int c)
...@@ -1141,20 +1158,30 @@ to_int(int c) ...@@ -1141,20 +1158,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 * static PyObject *
binascii_unhexlify(PyObject *self, PyObject *args) binascii_a2b_hex_impl(PyModuleDef *module, Py_buffer *hexstr)
/*[clinic end generated code: checksum=d61da452b5c6d2903c32c3e90e6a97221b25989b]*/
{ {
Py_buffer parg;
char* argbuf; char* argbuf;
Py_ssize_t arglen; Py_ssize_t arglen;
PyObject *retval; PyObject *retval;
char* retbuf; char* retbuf;
Py_ssize_t i, j; Py_ssize_t i, j;
if (!PyArg_ParseTuple(args, "O&:a2b_hex", ascii_buffer_converter, &parg)) argbuf = hexstr->buf;
return NULL; arglen = hexstr->len;
argbuf = parg.buf;
arglen = parg.len;
assert(arglen >= 0); assert(arglen >= 0);
...@@ -1163,16 +1190,13 @@ binascii_unhexlify(PyObject *self, PyObject *args) ...@@ -1163,16 +1190,13 @@ binascii_unhexlify(PyObject *self, PyObject *args)
* raise an exception. * raise an exception.
*/ */
if (arglen % 2) { if (arglen % 2) {
PyBuffer_Release(&parg);
PyErr_SetString(Error, "Odd-length string"); PyErr_SetString(Error, "Odd-length string");
return NULL; return NULL;
} }
retval = PyBytes_FromStringAndSize(NULL, (arglen/2)); retval = PyBytes_FromStringAndSize(NULL, (arglen/2));
if (!retval) { if (!retval)
PyBuffer_Release(&parg);
return NULL; return NULL;
}
retbuf = PyBytes_AS_STRING(retval); retbuf = PyBytes_AS_STRING(retval);
for (i=j=0; i < arglen; i += 2) { for (i=j=0; i < arglen; i += 2) {
...@@ -1185,21 +1209,13 @@ binascii_unhexlify(PyObject *self, PyObject *args) ...@@ -1185,21 +1209,13 @@ binascii_unhexlify(PyObject *self, PyObject *args)
} }
retbuf[j++] = (top << 4) + bot; retbuf[j++] = (top << 4) + bot;
} }
PyBuffer_Release(&parg);
return retval; return retval;
finally: finally:
PyBuffer_Release(&parg);
Py_DECREF(retval); Py_DECREF(retval);
return NULL; 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()\"");
static int table_hex[128] = { static int table_hex[128] = {
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
...@@ -1215,25 +1231,29 @@ static int table_hex[128] = { ...@@ -1215,25 +1231,29 @@ static int table_hex[128] = {
#define MAXLINESIZE 76 #define MAXLINESIZE 76
PyDoc_STRVAR(doc_a2b_qp, "Decode a string of qp-encoded data");
static PyObject* /*[clinic input]
binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) binascii.a2b_qp
ascii: 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 *ascii, int header)
/*[clinic end generated code: checksum=33910d5b347bf9f33203769e649f35ea41694b71]*/
{ {
Py_ssize_t in, out; Py_ssize_t in, out;
char ch; char ch;
Py_buffer pdata;
unsigned char *data, *odata; unsigned char *data, *odata;
Py_ssize_t datalen = 0; Py_ssize_t datalen = 0;
PyObject *rv; PyObject *rv;
static char *kwlist[] = {"data", "header", NULL};
int header = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i:a2b_qp", kwlist, data = ascii->buf;
ascii_buffer_converter, &pdata, &header)) datalen = ascii->len;
return NULL;
data = pdata.buf;
datalen = pdata.len;
/* We allocate the output same size as input, this is overkill. /* We allocate the output same size as input, this is overkill.
* The previous implementation used calloc() so we'll zero out the * The previous implementation used calloc() so we'll zero out the
...@@ -1241,7 +1261,6 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -1241,7 +1261,6 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
*/ */
odata = (unsigned char *) PyMem_Malloc(datalen); odata = (unsigned char *) PyMem_Malloc(datalen);
if (odata == NULL) { if (odata == NULL) {
PyBuffer_Release(&pdata);
PyErr_NoMemory(); PyErr_NoMemory();
return NULL; return NULL;
} }
...@@ -1292,11 +1311,9 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -1292,11 +1311,9 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
} }
} }
if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) {
PyBuffer_Release(&pdata);
PyMem_Free(odata); PyMem_Free(odata);
return NULL; return NULL;
} }
PyBuffer_Release(&pdata);
PyMem_Free(odata); PyMem_Free(odata);
return rv; return rv;
} }
...@@ -1312,62 +1329,62 @@ to_hex (unsigned char ch, unsigned char *s) ...@@ -1312,62 +1329,62 @@ to_hex (unsigned char ch, unsigned char *s)
return 0; 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 /* XXX: This is ridiculously complicated to be backward compatible
* (mostly) with the quopri module. It doesn't re-create the quopri * (mostly) with the quopri module. It doesn't re-create the quopri
* module bug where text ending in CRLF has the CR encoded */ * 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: checksum=ff2991ba640fff3e67ac63205801c7173a0366cd]*/
{ {
Py_ssize_t in, out; Py_ssize_t in, out;
Py_buffer pdata; unsigned char *databuf, *odata;
unsigned char *data, *odata;
Py_ssize_t datalen = 0, odatalen = 0; Py_ssize_t datalen = 0, odatalen = 0;
PyObject *rv; PyObject *rv;
unsigned int linelen = 0; unsigned int linelen = 0;
static char *kwlist[] = {"data", "quotetabs", "istext",
"header", NULL};
int istext = 1;
int quotetabs = 0;
int header = 0;
unsigned char ch; unsigned char ch;
int crlf = 0; int crlf = 0;
unsigned char *p; unsigned char *p;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|iii", kwlist, &pdata, databuf = data->buf;
&quotetabs, &istext, &header)) datalen = data->len;
return NULL;
data = pdata.buf;
datalen = pdata.len;
/* See if this string is using CRLF line ends */ /* See if this string is using CRLF line ends */
/* XXX: this function has the side effect of converting all of /* XXX: this function has the side effect of converting all of
* the end of lines to be the same depending on this detection * the end of lines to be the same depending on this detection
* here */ * here */
p = (unsigned char *) memchr(data, '\n', datalen); p = (unsigned char *) memchr(databuf, '\n', datalen);
if ((p != NULL) && (p > data) && (*(p-1) == '\r')) if ((p != NULL) && (p > databuf) && (*(p-1) == '\r'))
crlf = 1; crlf = 1;
/* First, scan to see how many characters need to be encoded */ /* First, scan to see how many characters need to be encoded */
in = 0; in = 0;
while (in < datalen) { while (in < datalen) {
if ((data[in] > 126) || if ((databuf[in] > 126) ||
(data[in] == '=') || (databuf[in] == '=') ||
(header && data[in] == '_') || (header && databuf[in] == '_') ||
((data[in] == '.') && (linelen == 0) && ((databuf[in] == '.') && (linelen == 0) &&
(data[in+1] == '\n' || data[in+1] == '\r' || data[in+1] == 0)) || (databuf[in+1] == '\n' || databuf[in+1] == '\r' || databuf[in+1] == 0)) ||
(!istext && ((data[in] == '\r') || (data[in] == '\n'))) || (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) ||
((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) || ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) ||
((data[in] < 33) && ((databuf[in] < 33) &&
(data[in] != '\r') && (data[in] != '\n') && (databuf[in] != '\r') && (databuf[in] != '\n') &&
(quotetabs || ((data[in] != '\t') && (data[in] != ' '))))) (quotetabs || ((databuf[in] != '\t') && (databuf[in] != ' ')))))
{ {
if ((linelen + 3) >= MAXLINESIZE) { if ((linelen + 3) >= MAXLINESIZE) {
linelen = 0; linelen = 0;
...@@ -1382,26 +1399,26 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -1382,26 +1399,26 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
} }
else { else {
if (istext && if (istext &&
((data[in] == '\n') || ((databuf[in] == '\n') ||
((in+1 < datalen) && (data[in] == '\r') && ((in+1 < datalen) && (databuf[in] == '\r') &&
(data[in+1] == '\n')))) (databuf[in+1] == '\n'))))
{ {
linelen = 0; linelen = 0;
/* Protect against whitespace on end of line */ /* 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')))
odatalen += 2; odatalen += 2;
if (crlf) if (crlf)
odatalen += 2; odatalen += 2;
else else
odatalen += 1; odatalen += 1;
if (data[in] == '\r') if (databuf[in] == '\r')
in += 2; in += 2;
else else
in++; in++;
} }
else { else {
if ((in + 1 != datalen) && if ((in + 1 != datalen) &&
(data[in+1] != '\n') && (databuf[in+1] != '\n') &&
(linelen + 1) >= MAXLINESIZE) { (linelen + 1) >= MAXLINESIZE) {
linelen = 0; linelen = 0;
if (crlf) if (crlf)
...@@ -1422,7 +1439,6 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -1422,7 +1439,6 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
*/ */
odata = (unsigned char *) PyMem_Malloc(odatalen); odata = (unsigned char *) PyMem_Malloc(odatalen);
if (odata == NULL) { if (odata == NULL) {
PyBuffer_Release(&pdata);
PyErr_NoMemory(); PyErr_NoMemory();
return NULL; return NULL;
} }
...@@ -1430,17 +1446,17 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -1430,17 +1446,17 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
in = out = linelen = 0; in = out = linelen = 0;
while (in < datalen) { while (in < datalen) {
if ((data[in] > 126) || if ((databuf[in] > 126) ||
(data[in] == '=') || (databuf[in] == '=') ||
(header && data[in] == '_') || (header && databuf[in] == '_') ||
((data[in] == '.') && (linelen == 0) && ((databuf[in] == '.') && (linelen == 0) &&
(data[in+1] == '\n' || data[in+1] == '\r' || data[in+1] == 0)) || (databuf[in+1] == '\n' || databuf[in+1] == '\r' || databuf[in+1] == 0)) ||
(!istext && ((data[in] == '\r') || (data[in] == '\n'))) || (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) ||
((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) || ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) ||
((data[in] < 33) && ((databuf[in] < 33) &&
(data[in] != '\r') && (data[in] != '\n') && (databuf[in] != '\r') && (databuf[in] != '\n') &&
(quotetabs || (quotetabs ||
(!quotetabs && ((data[in] != '\t') && (data[in] != ' ')))))) (!quotetabs && ((databuf[in] != '\t') && (databuf[in] != ' '))))))
{ {
if ((linelen + 3 )>= MAXLINESIZE) { if ((linelen + 3 )>= MAXLINESIZE) {
odata[out++] = '='; odata[out++] = '=';
...@@ -1449,16 +1465,16 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -1449,16 +1465,16 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
linelen = 0; linelen = 0;
} }
odata[out++] = '='; odata[out++] = '=';
to_hex(data[in], &odata[out]); to_hex(databuf[in], &odata[out]);
out += 2; out += 2;
in++; in++;
linelen += 3; linelen += 3;
} }
else { else {
if (istext && if (istext &&
((data[in] == '\n') || ((databuf[in] == '\n') ||
((in+1 < datalen) && (data[in] == '\r') && ((in+1 < datalen) && (databuf[in] == '\r') &&
(data[in+1] == '\n')))) (databuf[in+1] == '\n'))))
{ {
linelen = 0; linelen = 0;
/* Protect against whitespace on end of line */ /* Protect against whitespace on end of line */
...@@ -1471,14 +1487,14 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -1471,14 +1487,14 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
if (crlf) odata[out++] = '\r'; if (crlf) odata[out++] = '\r';
odata[out++] = '\n'; odata[out++] = '\n';
if (data[in] == '\r') if (databuf[in] == '\r')
in += 2; in += 2;
else else
in++; in++;
} }
else { else {
if ((in + 1 != datalen) && if ((in + 1 != datalen) &&
(data[in+1] != '\n') && (databuf[in+1] != '\n') &&
(linelen + 1) >= MAXLINESIZE) { (linelen + 1) >= MAXLINESIZE) {
odata[out++] = '='; odata[out++] = '=';
if (crlf) odata[out++] = '\r'; if (crlf) odata[out++] = '\r';
...@@ -1486,22 +1502,20 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -1486,22 +1502,20 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
linelen = 0; linelen = 0;
} }
linelen++; linelen++;
if (header && data[in] == ' ') { if (header && databuf[in] == ' ') {
odata[out++] = '_'; odata[out++] = '_';
in++; in++;
} }
else { else {
odata[out++] = data[in++]; odata[out++] = databuf[in++];
} }
} }
} }
} }
if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) {
PyBuffer_Release(&pdata);
PyMem_Free(odata); PyMem_Free(odata);
return NULL; return NULL;
} }
PyBuffer_Release(&pdata);
PyMem_Free(odata); PyMem_Free(odata);
return rv; return rv;
} }
...@@ -1509,25 +1523,24 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -1509,25 +1523,24 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
/* List of functions defined in the module */ /* List of functions defined in the module */
static struct PyMethodDef binascii_module_methods[] = { static struct PyMethodDef binascii_module_methods[] = {
{"a2b_uu", binascii_a2b_uu, METH_VARARGS, doc_a2b_uu}, BINASCII_A2B_UU_METHODDEF
{"b2a_uu", binascii_b2a_uu, METH_VARARGS, doc_b2a_uu}, BINASCII_B2A_UU_METHODDEF
{"a2b_base64", binascii_a2b_base64, METH_VARARGS, doc_a2b_base64}, BINASCII_A2B_BASE64_METHODDEF
{"b2a_base64", binascii_b2a_base64, METH_VARARGS, doc_b2a_base64}, BINASCII_B2A_BASE64_METHODDEF
{"a2b_hqx", binascii_a2b_hqx, METH_VARARGS, doc_a2b_hqx}, BINASCII_A2B_HQX_METHODDEF
{"b2a_hqx", binascii_b2a_hqx, METH_VARARGS, doc_b2a_hqx}, BINASCII_B2A_HQX_METHODDEF
{"b2a_hex", binascii_hexlify, METH_VARARGS, doc_hexlify}, BINASCII_A2B_HEX_METHODDEF
{"a2b_hex", binascii_unhexlify, METH_VARARGS, doc_unhexlify}, BINASCII_B2A_HEX_METHODDEF
{"hexlify", binascii_hexlify, METH_VARARGS, doc_hexlify}, {"unhexlify", (PyCFunction)binascii_a2b_hex, METH_VARARGS,
{"unhexlify", binascii_unhexlify, METH_VARARGS, doc_unhexlify}, binascii_a2b_hex__doc__},
{"rlecode_hqx", binascii_rlecode_hqx, METH_VARARGS, doc_rlecode_hqx}, {"hexlify", (PyCFunction)binascii_b2a_hex, METH_VARARGS,
{"rledecode_hqx", binascii_rledecode_hqx, METH_VARARGS, binascii_b2a_hex__doc__},
doc_rledecode_hqx}, BINASCII_RLECODE_HQX_METHODDEF
{"crc_hqx", binascii_crc_hqx, METH_VARARGS, doc_crc_hqx}, BINASCII_RLEDECODE_HQX_METHODDEF
{"crc32", binascii_crc32, METH_VARARGS, doc_crc32}, BINASCII_CRC_HQX_METHODDEF
{"a2b_qp", (PyCFunction)binascii_a2b_qp, METH_VARARGS | METH_KEYWORDS, BINASCII_CRC32_METHODDEF
doc_a2b_qp}, BINASCII_A2B_QP_METHODDEF
{"b2a_qp", (PyCFunction)binascii_b2a_qp, METH_VARARGS | METH_KEYWORDS, BINASCII_B2A_QP_METHODDEF
doc_b2a_qp},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
......
/*[clinic input]
preserve
[clinic start generated code]*/
PyDoc_STRVAR(binascii_a2b_uu__doc__,
"a2b_uu(module, ascii)\n"
"Decode a line of uuencoded data.");
#define BINASCII_A2B_UU_METHODDEF \
{"a2b_uu", (PyCFunction)binascii_a2b_uu, METH_VARARGS, binascii_a2b_uu__doc__},
static PyObject *
binascii_a2b_uu_impl(PyModuleDef *module, Py_buffer *ascii);
static PyObject *
binascii_a2b_uu(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
Py_buffer ascii;
if (!PyArg_ParseTuple(args,
"O&:a2b_uu",
ascii_buffer_converter, &ascii))
goto exit;
return_value = binascii_a2b_uu_impl(module, &ascii);
exit:
return return_value;
}
PyDoc_STRVAR(binascii_b2a_uu__doc__,
"b2a_uu(module, data)\n"
"Uuencode line of data.");
#define BINASCII_B2A_UU_METHODDEF \
{"b2a_uu", (PyCFunction)binascii_b2a_uu, METH_VARARGS, binascii_b2a_uu__doc__},
static PyObject *
binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data);
static PyObject *
binascii_b2a_uu(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
Py_buffer data = {NULL, NULL};
if (!PyArg_ParseTuple(args,
"y*:b2a_uu",
&data))
goto exit;
return_value = binascii_b2a_uu_impl(module, &data);
exit:
/* Cleanup for data */
if (data.obj)
PyBuffer_Release(&data);
return return_value;
}
PyDoc_STRVAR(binascii_a2b_base64__doc__,
"a2b_base64(module, ascii)\n"
"Decode a line of base64 data.");
#define BINASCII_A2B_BASE64_METHODDEF \
{"a2b_base64", (PyCFunction)binascii_a2b_base64, METH_VARARGS, binascii_a2b_base64__doc__},
static PyObject *
binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *ascii);
static PyObject *
binascii_a2b_base64(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
Py_buffer ascii;
if (!PyArg_ParseTuple(args,
"O&:a2b_base64",
ascii_buffer_converter, &ascii))
goto exit;
return_value = binascii_a2b_base64_impl(module, &ascii);
exit:
return return_value;
}
PyDoc_STRVAR(binascii_b2a_base64__doc__,
"b2a_base64(module, data)\n"
"Base64-code line of data.");
#define BINASCII_B2A_BASE64_METHODDEF \
{"b2a_base64", (PyCFunction)binascii_b2a_base64, METH_VARARGS, binascii_b2a_base64__doc__},
static PyObject *
binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data);
static PyObject *
binascii_b2a_base64(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
Py_buffer data = {NULL, NULL};
if (!PyArg_ParseTuple(args,
"y*:b2a_base64",
&data))
goto exit;
return_value = binascii_b2a_base64_impl(module, &data);
exit:
/* Cleanup for data */
if (data.obj)
PyBuffer_Release(&data);
return return_value;
}
PyDoc_STRVAR(binascii_a2b_hqx__doc__,
"a2b_hqx(module, ascii)\n"
"Decode .hqx coding.");
#define BINASCII_A2B_HQX_METHODDEF \
{"a2b_hqx", (PyCFunction)binascii_a2b_hqx, METH_VARARGS, binascii_a2b_hqx__doc__},
static PyObject *
binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *ascii);
static PyObject *
binascii_a2b_hqx(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
Py_buffer ascii;
if (!PyArg_ParseTuple(args,
"O&:a2b_hqx",
ascii_buffer_converter, &ascii))
goto exit;
return_value = binascii_a2b_hqx_impl(module, &ascii);
exit:
return return_value;
}
PyDoc_STRVAR(binascii_rlecode_hqx__doc__,
"rlecode_hqx(module, data)\n"
"Binhex RLE-code binary data.");
#define BINASCII_RLECODE_HQX_METHODDEF \
{"rlecode_hqx", (PyCFunction)binascii_rlecode_hqx, METH_VARARGS, binascii_rlecode_hqx__doc__},
static PyObject *
binascii_rlecode_hqx_impl(PyModuleDef *module, Py_buffer *data);
static PyObject *
binascii_rlecode_hqx(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
Py_buffer data = {NULL, NULL};
if (!PyArg_ParseTuple(args,
"y*:rlecode_hqx",
&data))
goto exit;
return_value = binascii_rlecode_hqx_impl(module, &data);
exit:
/* Cleanup for data */
if (data.obj)
PyBuffer_Release(&data);
return return_value;
}
PyDoc_STRVAR(binascii_b2a_hqx__doc__,
"b2a_hqx(module, data)\n"
"Encode .hqx data.");
#define BINASCII_B2A_HQX_METHODDEF \
{"b2a_hqx", (PyCFunction)binascii_b2a_hqx, METH_VARARGS, binascii_b2a_hqx__doc__},
static PyObject *
binascii_b2a_hqx_impl(PyModuleDef *module, Py_buffer *data);
static PyObject *
binascii_b2a_hqx(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
Py_buffer data = {NULL, NULL};
if (!PyArg_ParseTuple(args,
"y*:b2a_hqx",
&data))
goto exit;
return_value = binascii_b2a_hqx_impl(module, &data);
exit:
/* Cleanup for data */
if (data.obj)
PyBuffer_Release(&data);
return return_value;
}
PyDoc_STRVAR(binascii_rledecode_hqx__doc__,
"rledecode_hqx(module, data)\n"
"Decode hexbin RLE-coded string.");
#define BINASCII_RLEDECODE_HQX_METHODDEF \
{"rledecode_hqx", (PyCFunction)binascii_rledecode_hqx, METH_VARARGS, binascii_rledecode_hqx__doc__},
static PyObject *
binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data);
static PyObject *
binascii_rledecode_hqx(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
Py_buffer data = {NULL, NULL};
if (!PyArg_ParseTuple(args,
"y*:rledecode_hqx",
&data))
goto exit;
return_value = binascii_rledecode_hqx_impl(module, &data);
exit:
/* Cleanup for data */
if (data.obj)
PyBuffer_Release(&data);
return return_value;
}
PyDoc_STRVAR(binascii_crc_hqx__doc__,
"crc_hqx(module, data, crc)\n"
"Compute hqx CRC incrementally.");
#define BINASCII_CRC_HQX_METHODDEF \
{"crc_hqx", (PyCFunction)binascii_crc_hqx, METH_VARARGS, binascii_crc_hqx__doc__},
static int
binascii_crc_hqx_impl(PyModuleDef *module, Py_buffer *data, int crc);
static PyObject *
binascii_crc_hqx(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
Py_buffer data = {NULL, NULL};
int crc;
int _return_value;
if (!PyArg_ParseTuple(args,
"y*i:crc_hqx",
&data, &crc))
goto exit;
_return_value = binascii_crc_hqx_impl(module, &data, crc);
if ((_return_value == -1) && PyErr_Occurred())
goto exit;
return_value = PyLong_FromLong((long)_return_value);
exit:
/* Cleanup for data */
if (data.obj)
PyBuffer_Release(&data);
return return_value;
}
PyDoc_STRVAR(binascii_crc32__doc__,
"crc32(module, data, crc=0)\n"
"Compute CRC-32 incrementally.");
#define BINASCII_CRC32_METHODDEF \
{"crc32", (PyCFunction)binascii_crc32, METH_VARARGS, binascii_crc32__doc__},
static unsigned int
binascii_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc);
static PyObject *
binascii_crc32(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
Py_buffer data = {NULL, NULL};
unsigned int crc = 0;
unsigned int _return_value;
if (!PyArg_ParseTuple(args,
"y*|I:crc32",
&data, &crc))
goto exit;
_return_value = binascii_crc32_impl(module, &data, crc);
if ((_return_value == -1) && PyErr_Occurred())
goto exit;
return_value = PyLong_FromUnsignedLong((unsigned long)_return_value);
exit:
/* Cleanup for data */
if (data.obj)
PyBuffer_Release(&data);
return return_value;
}
PyDoc_STRVAR(binascii_b2a_hex__doc__,
"b2a_hex(module, data)\n"
"Hexadecimal representation of binary data.\n"
"\n"
"The return value is a bytes object. This function is also\n"
"available as \"hexlify()\".");
#define BINASCII_B2A_HEX_METHODDEF \
{"b2a_hex", (PyCFunction)binascii_b2a_hex, METH_VARARGS, binascii_b2a_hex__doc__},
static PyObject *
binascii_b2a_hex_impl(PyModuleDef *module, Py_buffer *data);
static PyObject *
binascii_b2a_hex(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
Py_buffer data = {NULL, NULL};
if (!PyArg_ParseTuple(args,
"y*:b2a_hex",
&data))
goto exit;
return_value = binascii_b2a_hex_impl(module, &data);
exit:
/* Cleanup for data */
if (data.obj)
PyBuffer_Release(&data);
return return_value;
}
PyDoc_STRVAR(binascii_a2b_hex__doc__,
"a2b_hex(module, hexstr)\n"
"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()\".");
#define BINASCII_A2B_HEX_METHODDEF \
{"a2b_hex", (PyCFunction)binascii_a2b_hex, METH_VARARGS, binascii_a2b_hex__doc__},
static PyObject *
binascii_a2b_hex_impl(PyModuleDef *module, Py_buffer *hexstr);
static PyObject *
binascii_a2b_hex(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
Py_buffer hexstr;
if (!PyArg_ParseTuple(args,
"O&:a2b_hex",
ascii_buffer_converter, &hexstr))
goto exit;
return_value = binascii_a2b_hex_impl(module, &hexstr);
exit:
return return_value;
}
PyDoc_STRVAR(binascii_a2b_qp__doc__,
"a2b_qp(module, ascii, header=False)\n"
"Decode a string of qp-encoded data.");
#define BINASCII_A2B_QP_METHODDEF \
{"a2b_qp", (PyCFunction)binascii_a2b_qp, METH_VARARGS, binascii_a2b_qp__doc__},
static PyObject *
binascii_a2b_qp_impl(PyModuleDef *module, Py_buffer *ascii, int header);
static PyObject *
binascii_a2b_qp(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
Py_buffer ascii;
int header = 0;
if (!PyArg_ParseTuple(args,
"O&|i:a2b_qp",
ascii_buffer_converter, &ascii, &header))
goto exit;
return_value = binascii_a2b_qp_impl(module, &ascii, header);
exit:
return return_value;
}
PyDoc_STRVAR(binascii_b2a_qp__doc__,
"b2a_qp(module, data, quotetabs=False, istext=True, header=False)\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)\n"
"are both encoded. When quotetabs is set, space and tabs are encoded.");
#define BINASCII_B2A_QP_METHODDEF \
{"b2a_qp", (PyCFunction)binascii_b2a_qp, METH_VARARGS|METH_KEYWORDS, binascii_b2a_qp__doc__},
static PyObject *
binascii_b2a_qp_impl(PyModuleDef *module, Py_buffer *data, int quotetabs, int istext, int header);
static PyObject *
binascii_b2a_qp(PyModuleDef *module, PyObject *args, PyObject *kwargs)
{
PyObject *return_value = NULL;
static char *_keywords[] = {"data", "quotetabs", "istext", "header", NULL};
Py_buffer data = {NULL, NULL};
int quotetabs = 0;
int istext = 1;
int header = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"y*|iii:b2a_qp", _keywords,
&data, &quotetabs, &istext, &header))
goto exit;
return_value = binascii_b2a_qp_impl(module, &data, quotetabs, istext, header);
exit:
/* Cleanup for data */
if (data.obj)
PyBuffer_Release(&data);
return return_value;
}
/*[clinic end generated code: checksum=bd769a1cd1169bfa0b73a0ee3081b0748fc39e2c]*/
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment