[3.7] bpo-9566: Fix compiler warnings on Windows (GH-12920)
https://github.com/python/cpython/commit/8a9a6b443c57e47e9d10ed7775479aada4d... commit: 8a9a6b443c57e47e9d10ed7775479aada4dac719 branch: 3.7 author: Victor Stinner <vstinner@redhat.com> committer: GitHub <noreply@github.com> date: 2019-04-23T10:26:11+02:00 summary: [3.7] bpo-9566: Fix compiler warnings on Windows (GH-12920) * bpo-9566: Fix compiler warnings in gcmodule.c (GH-11010) Change PyDTrace_GC_DONE() argument type from int to Py_ssize_t. (cherry picked from commit edad38e3e05586ba58291f47756eb3fb808f5577) * bpo-30465: Fix C downcast warning on Windows in ast.c (#6593) ast.c: fstring_fix_node_location() downcasts a pointer difference to a C int. Replace int with Py_ssize_t to fix the compiler warning. (cherry picked from commit fb7e7992beec7f76cc2db77ab6ce1e86446bfccf) * bpo-9566: Fix compiler warnings in peephole.c (GH-10652) (cherry picked from commit 028f0ef4f3111d2b3fc5b971642e337ba7990873) * bpo-27645, sqlite: Fix integer overflow on sleep (#6594) Use the _PyTime_t type and round away from zero (ROUND_UP, _PyTime_ROUND_TIMEOUT) the sleep duration, when converting a Python object to seconds and then to milliseconds. Raise an OverflowError in case of overflow. Previously the (int)double conversion rounded towards zero (ROUND_DOWN). (cherry picked from commit ca405017d5e776a2e3d9291236e62d2e09489dd2) files: M Include/pydtrace.h M Modules/_sqlite/connection.c M Python/ast.c M Python/peephole.c diff --git a/Include/pydtrace.h b/Include/pydtrace.h index 037961d429c6..7a04278166b0 100644 --- a/Include/pydtrace.h +++ b/Include/pydtrace.h @@ -29,7 +29,7 @@ static inline void PyDTrace_LINE(const char *arg0, const char *arg1, int arg2) { static inline void PyDTrace_FUNCTION_ENTRY(const char *arg0, const char *arg1, int arg2) {} static inline void PyDTrace_FUNCTION_RETURN(const char *arg0, const char *arg1, int arg2) {} static inline void PyDTrace_GC_START(int arg0) {} -static inline void PyDTrace_GC_DONE(int arg0) {} +static inline void PyDTrace_GC_DONE(Py_ssize_t arg0) {} static inline void PyDTrace_INSTANCE_NEW_START(int arg0) {} static inline void PyDTrace_INSTANCE_NEW_DONE(int arg0) {} static inline void PyDTrace_INSTANCE_DELETE_START(int arg0) {} diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index d43286a2d34d..9eb61c18f304 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1462,17 +1462,33 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * const char *name = "main"; int rc; int callback_error = 0; - double sleep_secs = 0.250; + PyObject *sleep_obj = NULL; + int sleep_ms = 250; sqlite3 *bck_conn; sqlite3_backup *bck_handle; static char *keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsd:backup", keywords, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsO:backup", keywords, &pysqlite_ConnectionType, &target, - &pages, &progress, &name, &sleep_secs)) { + &pages, &progress, &name, &sleep_obj)) { return NULL; } + if (sleep_obj != NULL) { + _PyTime_t sleep_secs; + if (_PyTime_FromSecondsObject(&sleep_secs, sleep_obj, + _PyTime_ROUND_TIMEOUT)) { + return NULL; + } + _PyTime_t ms = _PyTime_AsMilliseconds(sleep_secs, + _PyTime_ROUND_TIMEOUT); + if (ms < INT_MIN || ms > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "sleep is too large"); + return NULL; + } + sleep_ms = (int)ms; + } + if (!pysqlite_check_connection((pysqlite_Connection *)target)) { return NULL; } @@ -1532,7 +1548,7 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * the engine could not make any progress */ if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED) { Py_BEGIN_ALLOW_THREADS - sqlite3_sleep(sleep_secs * 1000.0); + sqlite3_sleep(sleep_ms); Py_END_ALLOW_THREADS } } while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED); diff --git a/Python/ast.c b/Python/ast.c index 1e182c7d782a..ce61375ea951 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -4282,7 +4282,7 @@ fstring_fix_node_location(const node *parent, node *n, char *expr_str) break; start--; } - cols += substr - start; + cols += (int)(substr - start); /* Fix lineno in mulitline strings. */ while ((substr = strchr(substr + 1, '\n'))) lines--; diff --git a/Python/peephole.c b/Python/peephole.c index a3b078fdf1d4..95b3dbb6bf51 100644 --- a/Python/peephole.c +++ b/Python/peephole.c @@ -152,6 +152,15 @@ fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t codelen, PyTuple_SET_ITEM(newconst, i, constant); } + Py_ssize_t index = PyList_GET_SIZE(consts); +#if SIZEOF_SIZE_T > SIZEOF_INT + if ((size_t)index >= UINT_MAX - 1) { + Py_DECREF(newconst); + PyErr_SetString(PyExc_OverflowError, "too many constants"); + return -1; + } +#endif + /* Append folded constant onto consts */ if (PyList_Append(consts, newconst)) { Py_DECREF(newconst); @@ -160,7 +169,7 @@ fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t codelen, Py_DECREF(newconst); return copy_op_arg(codestr, c_start, LOAD_CONST, - PyList_GET_SIZE(consts)-1, opcode_end); + (unsigned int)index, opcode_end); } static unsigned int * @@ -223,7 +232,7 @@ PyObject * PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, PyObject *lnotab_obj) { - Py_ssize_t h, i, nexti, op_start, codelen, tgt; + Py_ssize_t h, i, nexti, op_start, tgt; unsigned int j, nops; unsigned char opcode, nextop; _Py_CODEUNIT *codestr = NULL; @@ -251,17 +260,22 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, the peephole optimizer doesn't modify line numbers. */ assert(PyBytes_Check(code)); - codelen = PyBytes_GET_SIZE(code); - assert(codelen % sizeof(_Py_CODEUNIT) == 0); + Py_ssize_t codesize = PyBytes_GET_SIZE(code); + assert(codesize % sizeof(_Py_CODEUNIT) == 0); + Py_ssize_t codelen = codesize / sizeof(_Py_CODEUNIT); + if (codelen > INT_MAX) { + /* Python assembler is limited to INT_MAX: see assembler.a_offset in + compile.c. */ + goto exitUnchanged; + } /* Make a modifiable copy of the code string */ - codestr = (_Py_CODEUNIT *)PyMem_Malloc(codelen); + codestr = (_Py_CODEUNIT *)PyMem_Malloc(codesize); if (codestr == NULL) { PyErr_NoMemory(); goto exitError; } - memcpy(codestr, PyBytes_AS_STRING(code), codelen); - codelen /= sizeof(_Py_CODEUNIT); + memcpy(codestr, PyBytes_AS_STRING(code), codesize); blocks = markblocks(codestr, codelen); if (blocks == NULL) @@ -359,7 +373,11 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, jump past it), and all conditional jumps pop their argument when they're not taken (so change the first jump to pop its argument when it's taken). */ - h = set_arg(codestr, i, (tgt + 1) * sizeof(_Py_CODEUNIT)); + Py_ssize_t arg = (tgt + 1); + /* cannot overflow: codelen <= INT_MAX */ + assert((size_t)arg <= UINT_MAX / sizeof(_Py_CODEUNIT)); + arg *= sizeof(_Py_CODEUNIT); + h = set_arg(codestr, i, (unsigned int)arg); j = opcode == JUMP_IF_TRUE_OR_POP ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE; } @@ -392,17 +410,20 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, codestr[op_start] = PACKOPARG(RETURN_VALUE, 0); fill_nops(codestr, op_start + 1, i + 1); } else if (UNCONDITIONAL_JUMP(_Py_OPCODE(codestr[tgt]))) { - j = GETJUMPTGT(codestr, tgt); + size_t arg = GETJUMPTGT(codestr, tgt); if (opcode == JUMP_FORWARD) { /* JMP_ABS can go backwards */ opcode = JUMP_ABSOLUTE; } else if (!ABSOLUTE_JUMP(opcode)) { - if ((Py_ssize_t)j < i + 1) { + if (arg < (size_t)(i + 1)) { break; /* No backward relative jumps */ } - j -= i + 1; /* Calc relative jump addr */ + arg -= i + 1; /* Calc relative jump addr */ } - j *= sizeof(_Py_CODEUNIT); - copy_op_arg(codestr, op_start, opcode, j, i + 1); + /* cannot overflow: codelen <= INT_MAX */ + assert(arg <= (UINT_MAX / sizeof(_Py_CODEUNIT))); + arg *= sizeof(_Py_CODEUNIT); + copy_op_arg(codestr, op_start, opcode, + (unsigned int)arg, i + 1); } break; @@ -422,11 +443,14 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, /* Fixup lnotab */ for (i = 0, nops = 0; i < codelen; i++) { - assert(i - nops <= INT_MAX); + size_t block = (size_t)i - nops; + /* cannot overflow: codelen <= INT_MAX */ + assert(block <= UINT_MAX); /* original code offset => new code offset */ - blocks[i] = i - nops; - if (_Py_OPCODE(codestr[i]) == NOP) + blocks[i] = (unsigned int)block; + if (_Py_OPCODE(codestr[i]) == NOP) { nops++; + } } cum_orig_offset = 0; last_offset = 0; @@ -473,12 +497,14 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, j *= sizeof(_Py_CODEUNIT); break; } - nexti = i - op_start + 1; - if (instrsize(j) > nexti) + Py_ssize_t ilen = i - op_start + 1; + if (instrsize(j) > ilen) { goto exitUnchanged; - /* If instrsize(j) < nexti, we'll emit EXTENDED_ARG 0 */ - write_op_arg(codestr + h, opcode, j, nexti); - h += nexti; + } + assert(ilen <= INT_MAX); + /* If instrsize(j) < ilen, we'll emit EXTENDED_ARG 0 */ + write_op_arg(codestr + h, opcode, j, (int)ilen); + h += ilen; } assert(h + (Py_ssize_t)nops == codelen);
participants (1)
-
Victor Stinner