diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2022-08-08 16:21:07 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-08 16:21:07 (GMT) |
commit | 62f06508e76e023a81861caee6a45e1d639bf530 (patch) | |
tree | 7314afc6ee3da212616d55d24cfd9e2a9853dcac /Objects | |
parent | 63140b445e4a303df430b3d60c1cd4ef34f27c03 (diff) | |
download | cpython-62f06508e76e023a81861caee6a45e1d639bf530.zip cpython-62f06508e76e023a81861caee6a45e1d639bf530.tar.gz cpython-62f06508e76e023a81861caee6a45e1d639bf530.tar.bz2 |
gh-95781: More strict format string checking in PyUnicode_FromFormatV() (GH-95784)
An unrecognized format character in PyUnicode_FromFormat() and
PyUnicode_FromFormatV() now sets a SystemError.
In previous versions it caused all the rest of the format string to be
copied as-is to the result string, and any extra arguments discarded.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/unicodeobject.c | 33 |
1 files changed, 10 insertions, 23 deletions
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 7ff7995..184a2bf 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2355,6 +2355,13 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, p = f; f++; + if (*f == '%') { + if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0) + return NULL; + f++; + return f; + } + zeropad = 0; if (*f == '0') { zeropad = 1; @@ -2392,14 +2399,6 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, f++; } } - if (*f == '%') { - /* "%.3%s" => f points to "3" */ - f--; - } - } - if (*f == '\0') { - /* bogus format "%.123" => go backward, f points to "3" */ - f--; } /* Handle %ld, %lu, %lld and %llu. */ @@ -2423,7 +2422,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, ++f; } - if (f[1] == '\0') + if (f[0] != '\0' && f[1] == '\0') writer->overallocate = 0; switch (*f) { @@ -2616,21 +2615,9 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, break; } - case '%': - if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0) - return NULL; - break; - default: - /* if we stumble upon an unknown formatting code, copy the rest - of the format string to the output string. (we cannot just - skip the code, since there's no way to know what's in the - argument list) */ - len = strlen(p); - if (_PyUnicodeWriter_WriteLatin1String(writer, p, len) == -1) - return NULL; - f = p+len; - return f; + PyErr_Format(PyExc_SystemError, "invalid format string: %s", p); + return NULL; } f++; |