Skip to content

Commit d4250a4

Browse files
committed
fix possible integer overflow in binascii.b2a_qp (closes #27760)
Reported by Thomas E. Hybel
1 parent 2108862 commit d4250a4

File tree

2 files changed

+18
-9
lines changed

2 files changed

+18
-9
lines changed

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ Core and Builtins
2929
Library
3030
-------
3131

32+
- Issue #27760: Fix possible integer overflow in binascii.b2a_qp.
33+
3234
- Issue #27758: Fix possible integer overflow in the _csv module for large record
3335
lengths.
3436

Modules/binascii.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,6 +1365,7 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
13651365
/* First, scan to see how many characters need to be encoded */
13661366
in = 0;
13671367
while (in < datalen) {
1368+
Py_ssize_t delta = 0;
13681369
if ((data[in] > 126) ||
13691370
(data[in] == '=') ||
13701371
(header && data[in] == '_') ||
@@ -1379,12 +1380,12 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
13791380
if ((linelen + 3) >= MAXLINESIZE) {
13801381
linelen = 0;
13811382
if (crlf)
1382-
odatalen += 3;
1383+
delta += 3;
13831384
else
1384-
odatalen += 2;
1385+
delta += 2;
13851386
}
13861387
linelen += 3;
1387-
odatalen += 3;
1388+
delta += 3;
13881389
in++;
13891390
}
13901391
else {
@@ -1396,11 +1397,11 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
13961397
linelen = 0;
13971398
/* Protect against whitespace on end of line */
13981399
if (in && ((data[in-1] == ' ') || (data[in-1] == '\t')))
1399-
odatalen += 2;
1400+
delta += 2;
14001401
if (crlf)
1401-
odatalen += 2;
1402+
delta += 2;
14021403
else
1403-
odatalen += 1;
1404+
delta += 1;
14041405
if (data[in] == '\r')
14051406
in += 2;
14061407
else
@@ -1412,15 +1413,21 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
14121413
(linelen + 1) >= MAXLINESIZE) {
14131414
linelen = 0;
14141415
if (crlf)
1415-
odatalen += 3;
1416+
delta += 3;
14161417
else
1417-
odatalen += 2;
1418+
delta += 2;
14181419
}
14191420
linelen++;
1420-
odatalen++;
1421+
delta++;
14211422
in++;
14221423
}
14231424
}
1425+
if (PY_SSIZE_T_MAX - delta < odatalen) {
1426+
PyBuffer_Release(&pdata);
1427+
PyErr_NoMemory();
1428+
return NULL;
1429+
}
1430+
odatalen += delta;
14241431
}
14251432

14261433
/* We allocate the output same size as input, this is overkill.

0 commit comments

Comments
 (0)