mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
gh-129813, PEP 782: Use PyBytesWriter in binascii (#138825)
Replace the private _PyBytesWriter API with the new public PyBytesWriter API.
This commit is contained in:
parent
805e3368d6
commit
ca99af3c5e
1 changed files with 50 additions and 47 deletions
|
|
@ -205,11 +205,9 @@ binascii_a2b_uu_impl(PyObject *module, Py_buffer *data)
|
||||||
/*[clinic end generated code: output=e027f8e0b0598742 input=7cafeaf73df63d1c]*/
|
/*[clinic end generated code: output=e027f8e0b0598742 input=7cafeaf73df63d1c]*/
|
||||||
{
|
{
|
||||||
const unsigned char *ascii_data;
|
const unsigned char *ascii_data;
|
||||||
unsigned char *bin_data;
|
|
||||||
int leftbits = 0;
|
int leftbits = 0;
|
||||||
unsigned char this_ch;
|
unsigned char this_ch;
|
||||||
unsigned int leftchar = 0;
|
unsigned int leftchar = 0;
|
||||||
PyObject *rv;
|
|
||||||
Py_ssize_t ascii_len, bin_len;
|
Py_ssize_t ascii_len, bin_len;
|
||||||
binascii_state *state;
|
binascii_state *state;
|
||||||
|
|
||||||
|
|
@ -223,9 +221,11 @@ binascii_a2b_uu_impl(PyObject *module, Py_buffer *data)
|
||||||
ascii_len--;
|
ascii_len--;
|
||||||
|
|
||||||
/* Allocate the buffer */
|
/* Allocate the buffer */
|
||||||
if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL )
|
PyBytesWriter *writer = PyBytesWriter_Create(bin_len);
|
||||||
|
if (writer == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
|
}
|
||||||
|
unsigned char *bin_data = PyBytesWriter_GetData(writer);
|
||||||
|
|
||||||
for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) {
|
for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) {
|
||||||
/* XXX is it really best to add NULs if there's no more data */
|
/* XXX is it really best to add NULs if there's no more data */
|
||||||
|
|
@ -245,11 +245,10 @@ binascii_a2b_uu_impl(PyObject *module, Py_buffer *data)
|
||||||
if ( this_ch < ' ' || this_ch > (' ' + 64)) {
|
if ( this_ch < ' ' || this_ch > (' ' + 64)) {
|
||||||
state = get_binascii_state(module);
|
state = get_binascii_state(module);
|
||||||
if (state == NULL) {
|
if (state == NULL) {
|
||||||
return NULL;
|
goto error;
|
||||||
}
|
}
|
||||||
PyErr_SetString(state->Error, "Illegal char");
|
PyErr_SetString(state->Error, "Illegal char");
|
||||||
Py_DECREF(rv);
|
goto error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
this_ch = (this_ch - ' ') & 077;
|
this_ch = (this_ch - ' ') & 077;
|
||||||
}
|
}
|
||||||
|
|
@ -277,14 +276,17 @@ binascii_a2b_uu_impl(PyObject *module, Py_buffer *data)
|
||||||
this_ch != '\n' && this_ch != '\r' ) {
|
this_ch != '\n' && this_ch != '\r' ) {
|
||||||
state = get_binascii_state(module);
|
state = get_binascii_state(module);
|
||||||
if (state == NULL) {
|
if (state == NULL) {
|
||||||
return NULL;
|
goto error;
|
||||||
}
|
}
|
||||||
PyErr_SetString(state->Error, "Trailing garbage");
|
PyErr_SetString(state->Error, "Trailing garbage");
|
||||||
Py_DECREF(rv);
|
goto error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rv;
|
return PyBytesWriter_Finish(writer);
|
||||||
|
|
||||||
|
error:
|
||||||
|
PyBytesWriter_Discard(writer);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
|
|
@ -302,16 +304,13 @@ static PyObject *
|
||||||
binascii_b2a_uu_impl(PyObject *module, Py_buffer *data, int backtick)
|
binascii_b2a_uu_impl(PyObject *module, Py_buffer *data, int backtick)
|
||||||
/*[clinic end generated code: output=b1b99de62d9bbeb8 input=beb27822241095cd]*/
|
/*[clinic end generated code: output=b1b99de62d9bbeb8 input=beb27822241095cd]*/
|
||||||
{
|
{
|
||||||
unsigned char *ascii_data;
|
|
||||||
const unsigned char *bin_data;
|
const unsigned char *bin_data;
|
||||||
int leftbits = 0;
|
int leftbits = 0;
|
||||||
unsigned char this_ch;
|
unsigned char this_ch;
|
||||||
unsigned int leftchar = 0;
|
unsigned int leftchar = 0;
|
||||||
binascii_state *state;
|
binascii_state *state;
|
||||||
Py_ssize_t bin_len, out_len;
|
Py_ssize_t bin_len;
|
||||||
_PyBytesWriter writer;
|
|
||||||
|
|
||||||
_PyBytesWriter_Init(&writer);
|
|
||||||
bin_data = data->buf;
|
bin_data = data->buf;
|
||||||
bin_len = data->len;
|
bin_len = data->len;
|
||||||
if ( bin_len > 45 ) {
|
if ( bin_len > 45 ) {
|
||||||
|
|
@ -325,10 +324,12 @@ binascii_b2a_uu_impl(PyObject *module, Py_buffer *data, int backtick)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're lazy and allocate to much (fixed up later) */
|
/* We're lazy and allocate to much (fixed up later) */
|
||||||
out_len = 2 + (bin_len + 2) / 3 * 4;
|
Py_ssize_t out_len = 2 + (bin_len + 2) / 3 * 4;
|
||||||
ascii_data = _PyBytesWriter_Alloc(&writer, out_len);
|
PyBytesWriter *writer = PyBytesWriter_Create(out_len);
|
||||||
if (ascii_data == NULL)
|
if (writer == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
unsigned char *ascii_data = PyBytesWriter_GetData(writer);
|
||||||
|
|
||||||
/* Store the length */
|
/* Store the length */
|
||||||
if (backtick && !bin_len)
|
if (backtick && !bin_len)
|
||||||
|
|
@ -356,7 +357,7 @@ binascii_b2a_uu_impl(PyObject *module, Py_buffer *data, int backtick)
|
||||||
}
|
}
|
||||||
*ascii_data++ = '\n'; /* Append a courtesy newline */
|
*ascii_data++ = '\n'; /* Append a courtesy newline */
|
||||||
|
|
||||||
return _PyBytesWriter_Finish(&writer, ascii_data);
|
return PyBytesWriter_FinishWithPointer(writer, ascii_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
|
|
@ -388,12 +389,11 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data, int strict_mode)
|
||||||
|
|
||||||
/* Allocate the buffer */
|
/* Allocate the buffer */
|
||||||
Py_ssize_t bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
|
Py_ssize_t bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
|
||||||
_PyBytesWriter writer;
|
PyBytesWriter *writer = PyBytesWriter_Create(bin_len);
|
||||||
_PyBytesWriter_Init(&writer);
|
if (writer == NULL) {
|
||||||
unsigned char *bin_data = _PyBytesWriter_Alloc(&writer, bin_len);
|
|
||||||
if (bin_data == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
unsigned char *bin_data_start = bin_data;
|
}
|
||||||
|
unsigned char *bin_data = PyBytesWriter_GetData(writer);
|
||||||
|
|
||||||
if (strict_mode && ascii_len > 0 && ascii_data[0] == '=') {
|
if (strict_mode && ascii_len > 0 && ascii_data[0] == '=') {
|
||||||
state = get_binascii_state(module);
|
state = get_binascii_state(module);
|
||||||
|
|
@ -489,12 +489,14 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data, int strict_mode)
|
||||||
state = get_binascii_state(module);
|
state = get_binascii_state(module);
|
||||||
if (state == NULL) {
|
if (state == NULL) {
|
||||||
/* error already set, from get_binascii_state */
|
/* error already set, from get_binascii_state */
|
||||||
|
assert(PyErr_Occurred());
|
||||||
} else if (quad_pos == 1) {
|
} else if (quad_pos == 1) {
|
||||||
/*
|
/*
|
||||||
** There is exactly one extra valid, non-padding, base64 character.
|
** There is exactly one extra valid, non-padding, base64 character.
|
||||||
** This is an invalid length, as there is no possible input that
|
** This is an invalid length, as there is no possible input that
|
||||||
** could encoded into such a base64 string.
|
** could encoded into such a base64 string.
|
||||||
*/
|
*/
|
||||||
|
unsigned char *bin_data_start = PyBytesWriter_GetData(writer);
|
||||||
PyErr_Format(state->Error,
|
PyErr_Format(state->Error,
|
||||||
"Invalid base64-encoded string: "
|
"Invalid base64-encoded string: "
|
||||||
"number of data characters (%zd) cannot be 1 more "
|
"number of data characters (%zd) cannot be 1 more "
|
||||||
|
|
@ -503,13 +505,15 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data, int strict_mode)
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(state->Error, "Incorrect padding");
|
PyErr_SetString(state->Error, "Incorrect padding");
|
||||||
}
|
}
|
||||||
error_end:
|
goto error_end;
|
||||||
_PyBytesWriter_Dealloc(&writer);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return _PyBytesWriter_Finish(&writer, bin_data);
|
return PyBytesWriter_FinishWithPointer(writer, bin_data);
|
||||||
|
|
||||||
|
error_end:
|
||||||
|
PyBytesWriter_Discard(writer);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -528,18 +532,15 @@ static PyObject *
|
||||||
binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline)
|
binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline)
|
||||||
/*[clinic end generated code: output=4ad62c8e8485d3b3 input=0e20ff59c5f2e3e1]*/
|
/*[clinic end generated code: output=4ad62c8e8485d3b3 input=0e20ff59c5f2e3e1]*/
|
||||||
{
|
{
|
||||||
unsigned char *ascii_data;
|
|
||||||
const unsigned char *bin_data;
|
const unsigned char *bin_data;
|
||||||
int leftbits = 0;
|
int leftbits = 0;
|
||||||
unsigned char this_ch;
|
unsigned char this_ch;
|
||||||
unsigned int leftchar = 0;
|
unsigned int leftchar = 0;
|
||||||
Py_ssize_t bin_len, out_len;
|
Py_ssize_t bin_len;
|
||||||
_PyBytesWriter writer;
|
|
||||||
binascii_state *state;
|
binascii_state *state;
|
||||||
|
|
||||||
bin_data = data->buf;
|
bin_data = data->buf;
|
||||||
bin_len = data->len;
|
bin_len = data->len;
|
||||||
_PyBytesWriter_Init(&writer);
|
|
||||||
|
|
||||||
assert(bin_len >= 0);
|
assert(bin_len >= 0);
|
||||||
|
|
||||||
|
|
@ -555,12 +556,15 @@ binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline)
|
||||||
/* We're lazy and allocate too much (fixed up later).
|
/* We're lazy and allocate too much (fixed up later).
|
||||||
"+2" leaves room for up to two pad characters.
|
"+2" leaves room for up to two pad characters.
|
||||||
Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */
|
Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */
|
||||||
out_len = bin_len*2 + 2;
|
Py_ssize_t out_len = bin_len*2 + 2;
|
||||||
if (newline)
|
if (newline) {
|
||||||
out_len++;
|
out_len++;
|
||||||
ascii_data = _PyBytesWriter_Alloc(&writer, out_len);
|
}
|
||||||
if (ascii_data == NULL)
|
PyBytesWriter *writer = PyBytesWriter_Create(out_len);
|
||||||
|
if (writer == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
unsigned char *ascii_data = PyBytesWriter_GetData(writer);
|
||||||
|
|
||||||
for( ; bin_len > 0 ; bin_len--, bin_data++ ) {
|
for( ; bin_len > 0 ; bin_len--, bin_data++ ) {
|
||||||
/* Shift the data into our buffer */
|
/* Shift the data into our buffer */
|
||||||
|
|
@ -585,7 +589,7 @@ binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline)
|
||||||
if (newline)
|
if (newline)
|
||||||
*ascii_data++ = '\n'; /* Append a courtesy newline */
|
*ascii_data++ = '\n'; /* Append a courtesy newline */
|
||||||
|
|
||||||
return _PyBytesWriter_Finish(&writer, ascii_data);
|
return PyBytesWriter_FinishWithPointer(writer, ascii_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -887,8 +891,6 @@ binascii_a2b_hex_impl(PyObject *module, Py_buffer *hexstr)
|
||||||
{
|
{
|
||||||
const char* argbuf;
|
const char* argbuf;
|
||||||
Py_ssize_t arglen;
|
Py_ssize_t arglen;
|
||||||
PyObject *retval;
|
|
||||||
char* retbuf;
|
|
||||||
Py_ssize_t i, j;
|
Py_ssize_t i, j;
|
||||||
binascii_state *state;
|
binascii_state *state;
|
||||||
|
|
||||||
|
|
@ -910,10 +912,11 @@ binascii_a2b_hex_impl(PyObject *module, Py_buffer *hexstr)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = PyBytes_FromStringAndSize(NULL, (arglen/2));
|
PyBytesWriter *writer = PyBytesWriter_Create(arglen/2);
|
||||||
if (!retval)
|
if (writer == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
retbuf = PyBytes_AS_STRING(retval);
|
}
|
||||||
|
char *retbuf = PyBytesWriter_GetData(writer);
|
||||||
|
|
||||||
for (i=j=0; i < arglen; i += 2) {
|
for (i=j=0; i < arglen; i += 2) {
|
||||||
unsigned int top = _PyLong_DigitValue[Py_CHARMASK(argbuf[i])];
|
unsigned int top = _PyLong_DigitValue[Py_CHARMASK(argbuf[i])];
|
||||||
|
|
@ -921,18 +924,18 @@ binascii_a2b_hex_impl(PyObject *module, Py_buffer *hexstr)
|
||||||
if (top >= 16 || bot >= 16) {
|
if (top >= 16 || bot >= 16) {
|
||||||
state = get_binascii_state(module);
|
state = get_binascii_state(module);
|
||||||
if (state == NULL) {
|
if (state == NULL) {
|
||||||
return NULL;
|
goto error;
|
||||||
}
|
}
|
||||||
PyErr_SetString(state->Error,
|
PyErr_SetString(state->Error,
|
||||||
"Non-hexadecimal digit found");
|
"Non-hexadecimal digit found");
|
||||||
goto finally;
|
goto error;
|
||||||
}
|
}
|
||||||
retbuf[j++] = (top << 4) + bot;
|
retbuf[j++] = (top << 4) + bot;
|
||||||
}
|
}
|
||||||
return retval;
|
return PyBytesWriter_Finish(writer);
|
||||||
|
|
||||||
finally:
|
error:
|
||||||
Py_DECREF(retval);
|
PyBytesWriter_Discard(writer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue