bpo-29568: Disable any characters between two percents for escaped percent "%%" in the format string for classic string formatting. (GH-513)
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index f0ddb95..3b15247 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -650,6 +650,12 @@
#endif
fmt++;
+ if (*fmt == '%') {
+ *res++ = '%';
+ fmt++;
+ fmtcnt--;
+ continue;
+ }
if (*fmt == '(') {
const char *keystart;
Py_ssize_t keylen;
@@ -794,11 +800,9 @@
"incomplete format");
goto error;
}
- if (c != '%') {
- v = getnextarg(args, arglen, &argidx);
- if (v == NULL)
- goto error;
- }
+ v = getnextarg(args, arglen, &argidx);
+ if (v == NULL)
+ goto error;
if (fmtcnt < 0) {
/* last writer: disable writer overallocation */
@@ -808,10 +812,6 @@
sign = 0;
fill = ' ';
switch (c) {
- case '%':
- *res++ = '%';
- continue;
-
case 'r':
// %r is only for 2/3 code; 3 only code should use %a
case 'a':
@@ -1017,7 +1017,7 @@
res += (width - len);
}
- if (dict && (argidx < arglen) && c != '%') {
+ if (dict && (argidx < arglen)) {
PyErr_SetString(PyExc_TypeError,
"not all arguments converted during bytes formatting");
Py_XDECREF(temp);
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index d3516fa..58899ad 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -14617,12 +14617,6 @@
if (ctx->fmtcnt == 0)
ctx->writer.overallocate = 0;
- if (arg->ch == '%') {
- if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0)
- return -1;
- return 1;
- }
-
v = unicode_format_getnextarg(ctx);
if (v == NULL)
return -1;
@@ -14882,6 +14876,13 @@
int ret;
arg.ch = PyUnicode_READ(ctx->fmtkind, ctx->fmtdata, ctx->fmtpos);
+ if (arg.ch == '%') {
+ ctx->fmtpos++;
+ ctx->fmtcnt--;
+ if (_PyUnicodeWriter_WriteCharInline(&ctx->writer, '%') < 0)
+ return -1;
+ return 0;
+ }
arg.flags = 0;
arg.width = -1;
arg.prec = -1;
@@ -14903,7 +14904,7 @@
return -1;
}
- if (ctx->dict && (ctx->argidx < ctx->arglen) && arg.ch != '%') {
+ if (ctx->dict && (ctx->argidx < ctx->arglen)) {
PyErr_SetString(PyExc_TypeError,
"not all arguments converted during string formatting");
return -1;