diff options
author | Benjamin Peterson <benjamin@python.org> | 2016-08-14 01:33:33 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2016-08-14 01:33:33 (GMT) |
commit | 6c08d9628a3035a122dcfbe064b3f8360b11daba (patch) | |
tree | 67ab3c8466ec324c1cb234ceccf95a2598ef53ba | |
parent | f670120cb76f0aa66ec29c683e740eddcf45ca4a (diff) | |
download | cpython-6c08d9628a3035a122dcfbe064b3f8360b11daba.zip cpython-6c08d9628a3035a122dcfbe064b3f8360b11daba.tar.gz cpython-6c08d9628a3035a122dcfbe064b3f8360b11daba.tar.bz2 |
fix possible integer overflow in binascii.b2a_qp (closes #27760)
Reported by Thomas E. Hybel
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | Modules/binascii.c | 25 |
2 files changed, 18 insertions, 9 deletions
@@ -29,6 +29,8 @@ Core and Builtins Library ------- +- Issue #27760: Fix possible integer overflow in binascii.b2a_qp. + - In the curses module, raise an error if window.getstr() is passed a negative value. diff --git a/Modules/binascii.c b/Modules/binascii.c index 0b492d5..8162045 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -1316,6 +1316,7 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) /* First, scan to see how many characters need to be encoded */ in = 0; while (in < datalen) { + Py_ssize_t delta = 0; if ((data[in] > 126) || (data[in] == '=') || (header && data[in] == '_') || @@ -1331,12 +1332,12 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) if ((linelen + 3) >= MAXLINESIZE) { linelen = 0; if (crlf) - odatalen += 3; + delta += 3; else - odatalen += 2; + delta += 2; } linelen += 3; - odatalen += 3; + delta += 3; in++; } else { @@ -1348,11 +1349,11 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) linelen = 0; /* Protect against whitespace on end of line */ if (in && ((data[in-1] == ' ') || (data[in-1] == '\t'))) - odatalen += 2; + delta += 2; if (crlf) - odatalen += 2; + delta += 2; else - odatalen += 1; + delta += 1; if (data[in] == '\r') in += 2; else @@ -1364,15 +1365,21 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) (linelen + 1) >= MAXLINESIZE) { linelen = 0; if (crlf) - odatalen += 3; + delta += 3; else - odatalen += 2; + delta += 2; } linelen++; - odatalen++; + delta++; in++; } } + if (PY_SSIZE_T_MAX - delta < odatalen) { + PyBuffer_Release(&pdata); + PyErr_NoMemory(); + return NULL; + } + odatalen += delta; } /* We allocate the output same size as input, this is overkill. |