diff options
Diffstat (limited to 'Python')
-rw-r--r-- | Python/asdl.c | 36 | ||||
-rw-r--r-- | Python/ast.c | 3 | ||||
-rw-r--r-- | Python/compile.c | 32 |
3 files changed, 63 insertions, 8 deletions
diff --git a/Python/asdl.c b/Python/asdl.c index 72329b9..1105d3a 100644 --- a/Python/asdl.c +++ b/Python/asdl.c @@ -5,8 +5,22 @@ asdl_seq * asdl_seq_new(int size, PyArena *arena) { asdl_seq *seq = NULL; - size_t n = sizeof(asdl_seq) + - (size ? (sizeof(void *) * (size - 1)) : 0); + size_t n = (size ? (sizeof(void *) * (size - 1)) : 0); + + /* check size is sane */ + if (size < 0 || size == INT_MIN || + (size && ((size - 1) > (PY_SIZE_MAX / sizeof(void *))))) { + PyErr_NoMemory(); + return NULL; + } + + /* check if size can be added safely */ + if (n > PY_SIZE_MAX - sizeof(asdl_seq)) { + PyErr_NoMemory(); + return NULL; + } + + n += sizeof(asdl_seq); seq = (asdl_seq *)PyArena_Malloc(arena, n); if (!seq) { @@ -22,8 +36,22 @@ asdl_int_seq * asdl_int_seq_new(int size, PyArena *arena) { asdl_int_seq *seq = NULL; - size_t n = sizeof(asdl_seq) + - (size ? (sizeof(int) * (size - 1)) : 0); + size_t n = (size ? (sizeof(void *) * (size - 1)) : 0); + + /* check size is sane */ + if (size < 0 || size == INT_MIN || + (size && ((size - 1) > (PY_SIZE_MAX / sizeof(void *))))) { + PyErr_NoMemory(); + return NULL; + } + + /* check if size can be added safely */ + if (n > PY_SIZE_MAX - sizeof(asdl_seq)) { + PyErr_NoMemory(); + return NULL; + } + + n += sizeof(asdl_seq); seq = (asdl_int_seq *)PyArena_Malloc(arena, n); if (!seq) { diff --git a/Python/ast.c b/Python/ast.c index da42a0e..79c9403 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -3145,6 +3145,9 @@ decode_unicode(struct compiling *c, const char *s, size_t len, int rawmode, cons buf = (char *)s; u = NULL; } else { + /* check for integer overflow */ + if (len > PY_SIZE_MAX / 4) + return NULL; /* "\XX" may become "\u005c\uHHLL" (12 bytes) */ u = PyBytes_FromStringAndSize((char *)NULL, len * 4); if (u == NULL) diff --git a/Python/compile.c b/Python/compile.c index 6017b2c..942ca1f52 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -227,6 +227,10 @@ _Py_Mangle(PyObject *privateobj, PyObject *ident) return ident; /* Don't mangle if class is just underscores */ } plen = Py_UNICODE_strlen(p); + + assert(1 <= PY_SSIZE_T_MAX - nlen); + assert(1 + nlen <= PY_SSIZE_T_MAX - plen); + ident = PyUnicode_FromStringAndSize(NULL, 1 + nlen + plen); if (!ident) return 0; @@ -635,6 +639,12 @@ compiler_next_instr(struct compiler *c, basicblock *b) size_t oldsize, newsize; oldsize = b->b_ialloc * sizeof(struct instr); newsize = oldsize << 1; + + if (oldsize > (PY_SIZE_MAX >> 1)) { + PyErr_NoMemory(); + return -1; + } + if (newsize == 0) { PyErr_NoMemory(); return -1; @@ -3711,6 +3721,10 @@ assemble_init(struct assembler *a, int nblocks, int firstlineno) a->a_lnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); if (!a->a_lnotab) return 0; + if (nblocks > PY_SIZE_MAX / sizeof(basicblock *)) { + PyErr_NoMemory(); + return 0; + } a->a_postorder = (basicblock **)PyObject_Malloc( sizeof(basicblock *) * nblocks); if (!a->a_postorder) { @@ -3819,10 +3833,14 @@ assemble_lnotab(struct assembler *a, struct instr *i) nbytes = a->a_lnotab_off + 2 * ncodes; len = PyBytes_GET_SIZE(a->a_lnotab); if (nbytes >= len) { - if (len * 2 < nbytes) + if ((len <= INT_MAX / 2) && (len * 2 < nbytes)) len = nbytes; - else + else if (len <= INT_MAX / 2) len *= 2; + else { + PyErr_NoMemory(); + return 0; + } if (_PyBytes_Resize(&a->a_lnotab, len) < 0) return 0; } @@ -3841,10 +3859,14 @@ assemble_lnotab(struct assembler *a, struct instr *i) nbytes = a->a_lnotab_off + 2 * ncodes; len = PyBytes_GET_SIZE(a->a_lnotab); if (nbytes >= len) { - if (len * 2 < nbytes) + if ((len <= INT_MAX / 2) && len * 2 < nbytes) len = nbytes; - else + else if (len <= INT_MAX / 2) len *= 2; + else { + PyErr_NoMemory(); + return 0; + } if (_PyBytes_Resize(&a->a_lnotab, len) < 0) return 0; } @@ -3903,6 +3925,8 @@ assemble_emit(struct assembler *a, struct instr *i) if (i->i_lineno && !assemble_lnotab(a, i)) return 0; if (a->a_offset + size >= len) { + if (len > PY_SSIZE_T_MAX / 2) + return 0; if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0) return 0; } |