Merge in release25-maint r60793:
Added checks for integer overflows, contributed by Google. Some are
only available if asserts are left in the code, in cases where they
can't be triggered from Python code.
diff --git a/Python/compile.c b/Python/compile.c
index c81218d..264fdcd 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -216,6 +216,10 @@
return ident; /* Don't mangle if class is just underscores */
}
plen = strlen(p);
+
+ assert(1 <= PY_SSIZE_T_MAX - nlen);
+ assert(1 + nlen <= PY_SSIZE_T_MAX - plen);
+
ident = PyString_FromStringAndSize(NULL, 1 + nlen + plen);
if (!ident)
return 0;
@@ -621,6 +625,12 @@
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;
@@ -3478,6 +3488,10 @@
a->a_lnotab = PyString_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) {
@@ -3586,10 +3600,14 @@
nbytes = a->a_lnotab_off + 2 * ncodes;
len = PyString_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 (_PyString_Resize(&a->a_lnotab, len) < 0)
return 0;
}
@@ -3608,10 +3626,14 @@
nbytes = a->a_lnotab_off + 2 * ncodes;
len = PyString_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 (_PyString_Resize(&a->a_lnotab, len) < 0)
return 0;
}
@@ -3670,6 +3692,8 @@
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 (_PyString_Resize(&a->a_bytecode, len * 2) < 0)
return 0;
}