Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Modules/_struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -2498,7 +2498,8 @@ Struct_pack_impl(PyStructObject *self, PyObject * const *values,
return NULL;
}

return PyBytesWriter_FinishWithSize(writer, self->s_size);
assert(PyBytesWriter_GetSize(writer) == self->s_size);
return PyBytesWriter_Finish(writer);
}

/*[clinic input]
Expand Down
101 changes: 52 additions & 49 deletions Objects/bytesobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -3731,12 +3731,6 @@ _PyBytes_RepeatBuffer(char* dest, Py_ssize_t len_dest,
// one extra NUL byte which is a common error.
#define PyBytesWriter_CANARY_BYTE PYMEM_DEADBYTE

static inline char*
byteswriter_data(PyBytesWriter *writer)
{
return _PyBytesWriter_GetData(writer);
}


static inline Py_ssize_t
byteswriter_allocated(PyBytesWriter *writer)
Expand All @@ -3758,7 +3752,7 @@ byteswriter_allocated(PyBytesWriter *writer)
static void
byteswriter_write_canary_byte(PyBytesWriter *writer)
{
unsigned char *data = (unsigned char*)byteswriter_data(writer);
unsigned char *data = (unsigned char*)_PyBytesWriter_GetData(writer);
data[writer->size] = PyBytesWriter_CANARY_BYTE;
}

Expand All @@ -3770,7 +3764,7 @@ byteswriter_reset_trailing_byte(PyBytesWriter *writer)
// bytes/bytearray expects the last byte to be a null byte.
// Reset the last byte to null for bytes/bytearray.
Py_ssize_t allocated = byteswriter_allocated(writer);
char *data = byteswriter_data(writer);
char *data = _PyBytesWriter_GetData(writer);
data[allocated] = '\0';
}
#endif
Expand Down Expand Up @@ -3801,7 +3795,7 @@ byteswriter_check_consistency(PyBytesWriter *writer)
}

#ifdef Py_DEBUG
const unsigned char *data = (const unsigned char*)byteswriter_data(writer);
const unsigned char *data = (const unsigned char*)_PyBytesWriter_GetData(writer);
unsigned char canary = data[writer->size];
if (canary != PyBytesWriter_CANARY_BYTE) {
_Py_FatalErrorFormat(__func__,
Expand Down Expand Up @@ -3895,7 +3889,7 @@ byteswriter_resize(PyBytesWriter *writer, Py_ssize_t new_size, int resize)
if (resize) {
Py_ssize_t old_size = writer->size;
assert(allocated > old_size);
memset(byteswriter_data(writer) + old_size, PyBytesWrite_NEW_BYTE,
memset(_PyBytesWriter_GetData(writer) + old_size, PyBytesWrite_NEW_BYTE,
allocated - old_size);
}
#endif
Expand All @@ -3921,24 +3915,25 @@ byteswriter_create(Py_ssize_t size, int use_bytearray)
}
}
writer->obj = NULL;
writer->size = 0;
writer->size = size;
writer->use_bytearray = use_bytearray;
writer->overallocate = !use_bytearray;

if (size >= 1) {
Py_ssize_t allocated = sizeof(writer->small_buffer) - 1;
if (size > allocated) {
if (byteswriter_resize(writer, size, 0) < 0) {
#ifdef Py_DEBUG
// Write the canary byte so byteswriter_check_consistency()
// doesn't fail in PyBytesWriter_Discard()
writer->size = 0;
byteswriter_write_canary_byte(writer);
#endif
PyBytesWriter_Discard(writer);
return NULL;
}
writer->size = size;
}
#ifdef Py_DEBUG
memset(byteswriter_data(writer), PyBytesWrite_NEW_BYTE,
memset(_PyBytesWriter_GetData(writer), PyBytesWrite_NEW_BYTE,
byteswriter_allocated(writer));
byteswriter_write_canary_byte(writer);
#endif
Expand Down Expand Up @@ -3967,34 +3962,23 @@ PyBytesWriter_Discard(PyBytesWriter *writer)
}

assert(byteswriter_check_consistency(writer));
#ifdef Py_DEBUG
if (writer->obj != NULL) {
#ifdef Py_DEBUG
byteswriter_reset_trailing_byte(writer);
}
#endif

Py_XDECREF(writer->obj);
Py_DECREF(writer->obj);
}
_Py_FREELIST_FREE(bytes_writers, writer, PyMem_Free);
}


PyObject*
PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)
static inline PyObject*
byteswriter_finish_with_size(PyBytesWriter *writer, Py_ssize_t final_size)
{
assert(byteswriter_check_consistency(writer));

if (size < 0) {
PyErr_Format(PyExc_ValueError, "size must be positive");
goto error;
}

if (size > writer->size) {
PyErr_SetString(PyExc_ValueError, "size larger than allocated size");
goto error;
}

PyObject *result;
if (size == 0 && !writer->use_bytearray) {
if (final_size == 0 && !writer->use_bytearray) {
result = bytes_get_empty();
if (writer->obj != NULL) {
#ifdef Py_DEBUG
Expand All @@ -4011,19 +3995,19 @@ PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)
#endif

if (writer->use_bytearray) {
if (size != PyByteArray_GET_SIZE(writer->obj)) {
if (PyByteArray_Resize(writer->obj, size)) {
if (final_size != PyByteArray_GET_SIZE(writer->obj)) {
if (PyByteArray_Resize(writer->obj, final_size)) {
goto error;
}
}
}
else {
if (size == 1) {
if (final_size == 1) {
unsigned char ch = PyBytes_AS_STRING(writer->obj)[0];
Py_SETREF(writer->obj, bytes_get_char(ch));
}
else if (size != PyBytes_GET_SIZE(writer->obj)) {
if (bytes_resize_inplace(&writer->obj, size)) {
else if (final_size != PyBytes_GET_SIZE(writer->obj)) {
if (bytes_resize_inplace(&writer->obj, final_size)) {
goto error;
}
}
Expand All @@ -4036,18 +4020,18 @@ PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)
// Create an object from the small buffer
const char *buffer = (const char *)writer->small_buffer;
if (writer->use_bytearray) {
result = PyByteArray_FromStringAndSize(buffer, size);
result = PyByteArray_FromStringAndSize(buffer, final_size);
}
else {
if (size == 1) {
if (final_size == 1) {
result = bytes_get_char((uint8_t)buffer[0]);
}
else {
result = bytes_alloc(size);
result = bytes_alloc(final_size);
if (result == NULL) {
goto error;
}
memcpy(PyBytes_AS_STRING(result), buffer, size);
memcpy(PyBytes_AS_STRING(result), buffer, final_size);
}
}
}
Expand All @@ -4061,17 +4045,36 @@ PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)
return NULL;
}

PyObject*
PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)
{
if (size < 0) {
PyErr_Format(PyExc_ValueError, "size must be positive");
goto error;
}
if (size > writer->size) {
PyErr_SetString(PyExc_ValueError, "size larger than allocated size");
goto error;
}
return byteswriter_finish_with_size(writer, size);

error:
PyBytesWriter_Discard(writer);
return NULL;
}

PyObject*
PyBytesWriter_Finish(PyBytesWriter *writer)
{
return PyBytesWriter_FinishWithSize(writer, writer->size);
return byteswriter_finish_with_size(writer, writer->size);
}


PyObject*
PyBytesWriter_FinishWithPointer(PyBytesWriter *writer, void *buf)
{
Py_ssize_t size = (char*)buf - byteswriter_data(writer);
Py_ssize_t size = (char*)buf - _PyBytesWriter_GetData(writer);
// Call PyBytesWriter_FinishWithSize() to check size
return PyBytesWriter_FinishWithSize(writer, size);
}

Expand All @@ -4081,7 +4084,7 @@ PyBytesWriter_GetData(PyBytesWriter *writer)
{
assert(byteswriter_check_consistency(writer));

return byteswriter_data(writer);
return _PyBytesWriter_GetData(writer);
}


Expand Down Expand Up @@ -4125,11 +4128,11 @@ static void*
_PyBytesWriter_ResizeAndUpdatePointer(PyBytesWriter *writer, Py_ssize_t size,
void *data)
{
Py_ssize_t pos = (char*)data - byteswriter_data(writer);
Py_ssize_t pos = (char*)data - _PyBytesWriter_GetData(writer);
if (PyBytesWriter_Resize(writer, size) < 0) {
return NULL;
}
return byteswriter_data(writer) + pos;
return _PyBytesWriter_GetData(writer) + pos;
}


Expand Down Expand Up @@ -4176,11 +4179,11 @@ void*
PyBytesWriter_GrowAndUpdatePointer(PyBytesWriter *writer, Py_ssize_t size,
void *buf)
{
Py_ssize_t pos = (char*)buf - byteswriter_data(writer);
Py_ssize_t pos = (char*)buf - _PyBytesWriter_GetData(writer);
if (PyBytesWriter_Grow(writer, size) < 0) {
return NULL;
}
return byteswriter_data(writer) + pos;
return _PyBytesWriter_GetData(writer) + pos;
}


Expand All @@ -4201,7 +4204,7 @@ PyBytesWriter_WriteBytes(PyBytesWriter *writer,
if (PyBytesWriter_Grow(writer, size) < 0) {
return -1;
}
char *buf = byteswriter_data(writer);
char *buf = _PyBytesWriter_GetData(writer);
memcpy(buf + pos, bytes, size);

assert(byteswriter_check_consistency(writer));
Expand Down Expand Up @@ -4232,7 +4235,7 @@ PyBytesWriter_Format(PyBytesWriter *writer, const char *format, ...)
return -1;
}

Py_ssize_t size = buf - byteswriter_data(writer);
Py_ssize_t size = buf - _PyBytesWriter_GetData(writer);
return PyBytesWriter_Resize(writer, size);
}

Expand Down
7 changes: 2 additions & 5 deletions Objects/unicodeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -4880,7 +4880,7 @@ _PyUnicode_EncodeUTF7(PyObject *str,
else { /* not in a shift sequence */
if (ch == '+') {
*out++ = '+';
*out++ = '-';
*out++ = '-';
}
else if (ENCODE_DIRECT(ch)) {
*out++ = (char) ch;
Expand Down Expand Up @@ -8644,10 +8644,7 @@ _PyUnicode_EncodeIconv(const char *encoding, PyObject *unicode,
iconv(cd, NULL, NULL, NULL, NULL);
}

if (PyBytesWriter_Resize(writer, out - (char *)PyBytesWriter_GetData(writer)) < 0) {
goto done;
}
result = PyBytesWriter_Finish(writer);
result = PyBytesWriter_FinishWithPointer(writer, out);
writer = NULL;

done:
Expand Down
2 changes: 1 addition & 1 deletion Python/assemble.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ assemble_free(struct assembler *a)

static inline void
write_except_byte(struct assembler *a, int byte) {
unsigned char *p = (unsigned char *) PyBytesWriter_GetData(a->a_except_table_writer);
unsigned char *p = PyBytesWriter_GetData(a->a_except_table_writer);
p[a->a_except_table_off++] = byte;
}

Expand Down
Loading