Skip to content

Commit d586ccb

Browse files
bpo-35552: Fix reading past the end in PyUnicode_FromFormat() and PyBytes_FromFormat(). (GH-11276)
Format characters "%s" and "%V" in PyUnicode_FromFormat() and "%s" in PyBytes_FromFormat() no longer read memory past the limit if precision is specified.
1 parent f1ec3ce commit d586ccb

File tree

3 files changed

+21
-6
lines changed

3 files changed

+21
-6
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Format characters ``%s`` and ``%V`` in :c:func:`PyUnicode_FromFormat` and
2+
``%s`` in :c:func:`PyBytes_FromFormat` no longer read memory past the
3+
limit if *precision* is specified.

Objects/bytesobject.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,15 @@ PyBytes_FromFormatV(const char *format, va_list vargs)
312312
Py_ssize_t i;
313313

314314
p = va_arg(vargs, const char*);
315-
i = strlen(p);
316-
if (prec > 0 && i > prec)
317-
i = prec;
315+
if (prec <= 0) {
316+
i = strlen(p);
317+
}
318+
else {
319+
i = 0;
320+
while (i < prec && p[i]) {
321+
i++;
322+
}
323+
}
318324
s = _PyBytesWriter_WriteBytes(&writer, s, p, i);
319325
if (s == NULL)
320326
goto error;

Objects/unicodeobject.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2578,9 +2578,15 @@ unicode_fromformat_write_cstr(_PyUnicodeWriter *writer, const char *str,
25782578
PyObject *unicode;
25792579
int res;
25802580

2581-
length = strlen(str);
2582-
if (precision != -1)
2583-
length = Py_MIN(length, precision);
2581+
if (precision == -1) {
2582+
length = strlen(str);
2583+
}
2584+
else {
2585+
length = 0;
2586+
while (length < precision && str[length]) {
2587+
length++;
2588+
}
2589+
}
25842590
unicode = PyUnicode_DecodeUTF8Stateful(str, length, "replace", NULL);
25852591
if (unicode == NULL)
25862592
return -1;

0 commit comments

Comments
 (0)