Skip to content
Open
Changes from 1 commit
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
Prev Previous commit
Next Next commit
simplify checks by using b_len/unitsize. use INT_MAX..
  • Loading branch information
sweeneyde committed Jul 26, 2022
commit 75a08cd7239dcd84de3aaac790001571b227454a
43 changes: 22 additions & 21 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -7541,29 +7541,27 @@ assemble_emit_exception_table_item(struct assembler *a, int value, int msb)
write_except_byte(a, (value&0x3f) | msb);
}

/* Make room for at least (logical_length+to_add)*unitsize in the
bytes object. Use exponential growth for O(1) amortized runtime. */
/* Make room for at least (logical_length+to_add)*unitsize bytes in the
bytes object. Use exponential growth for O(1) amortized runtime.
Keep len(bytes)/unitsize <= INT_MAX. */
static int
bytes_make_room(PyObject **bytes, int logical_length,
int to_add, Py_ssize_t unitsize)
bytes_make_room(PyObject **bytes, Py_ssize_t unitsize,
int logical_length, int to_add, const char *overflow_msg)
{
// Make sure we can successfully do the addition.
if (logical_length > INT_MAX - to_add) {
PyErr_NoMemory();
return 0;
}
// The existing logical buffer should always fit in a Py_ssize_t
assert(logical_length <= PY_SSIZE_T_MAX / unitsize);
Py_ssize_t b_len = PyBytes_GET_SIZE(*bytes);
if (unitsize * logical_length >= b_len - to_add * unitsize) {
Py_ssize_t space = b_len / unitsize;
assert(space <= INT_MAX);
assert(logical_length <= space);
if (logical_length >= space - to_add) {
// There's not enough room. Double it.
if (b_len > PY_SSIZE_T_MAX / 2) {
PyErr_NoMemory();
if (space > INT_MAX / 2 || b_len > PY_SSIZE_T_MAX / 2) {
PyErr_SetString(PyExc_OverflowError, overflow_msg);
return 0;
}
if (_PyBytes_Resize(bytes, b_len * 2) < 0) {
if (_PyBytes_Resize(bytes, PyBytes_GET_SIZE(*bytes) * 2) < 0) {
return 0;
}
assert(PyBytes_GET_SIZE(*bytes) / unitsize <= INT_MAX);
}
return 1;
}
Expand All @@ -7574,8 +7572,9 @@ bytes_make_room(PyObject **bytes, int logical_length,
static int
assemble_emit_exception_table_entry(struct assembler *a, int start, int end, basicblock *handler)
{
if (!bytes_make_room(&a->a_except_table, a->a_except_table_off,
MAX_SIZE_OF_ENTRY, 1)) {
if (!bytes_make_room(&a->a_except_table, sizeof(char),
a->a_except_table_off, MAX_SIZE_OF_ENTRY,
"exception table is too long")) {
return 0;
}
int size = end-start;
Expand Down Expand Up @@ -7717,8 +7716,9 @@ write_location_info_no_column(struct assembler* a, int length, int line_delta)
static int
write_location_info_entry(struct assembler* a, struct instr* i, int isize)
{
if (!bytes_make_room(&a->a_linetable, a->a_location_off,
THEORETICAL_MAX_ENTRY_SIZE, 1)) {
if (!bytes_make_room(&a->a_linetable, sizeof(char),
a->a_location_off, THEORETICAL_MAX_ENTRY_SIZE,
"line number table is too long")) {
return 0;
}
if (i->i_loc.lineno < 0) {
Expand Down Expand Up @@ -7776,8 +7776,9 @@ assemble_emit(struct assembler *a, struct instr *i)
{
_Py_CODEUNIT *code;
int size = instr_size(i);
if (!bytes_make_room(&a->a_bytecode, a->a_offset,
size, sizeof(_Py_CODEUNIT))) {
assert(a->a_offset <= INT_MAX / sizeof(_Py_CODEUNIT));
if (!bytes_make_room(&a->a_bytecode, sizeof(_Py_CODEUNIT),
a->a_offset, size, "bytecode is too long")) {
return 0;
}
code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset;
Expand Down