diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index 3ca14fac816..531bc223ff3 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -785,8 +785,19 @@ FORMAT_STRING(PyObject* value, PyObject* args) break; default: /* unknown */ - PyErr_Format(PyExc_ValueError, "Unknown conversion type %c", - format.type); + #if STRINGLIB_IS_UNICODE + /* If STRINGLIB_CHAR is Py_UNICODE, %c might be out-of-range, + hence the two cases. If it is char, gcc complains that the + condition below is always true, hence the ifdef. */ + if (format.type > 32 && format.type <128) + #endif + PyErr_Format(PyExc_ValueError, "Unknown conversion type %c", + (char)format.type); + #if STRINGLIB_IS_UNICODE + else + PyErr_Format(PyExc_ValueError, "Unknown conversion type '\\x%x'", + (unsigned int)format.type); + #endif goto done; } diff --git a/Objects/stringlib/string_format.h b/Objects/stringlib/string_format.h index 214b7b33ab7..be8e8080851 100644 --- a/Objects/stringlib/string_format.h +++ b/Objects/stringlib/string_format.h @@ -740,9 +740,17 @@ do_conversion(PyObject *obj, STRINGLIB_CHAR conversion) case 's': return STRINGLIB_TOSTR(obj); default: - PyErr_Format(PyExc_ValueError, - "Unknown converion specifier %c", - conversion); + if (conversion > 32 && conversion < 127) { + /* It's the ASCII subrange; casting to char is safe + (assuming the execution character set is an ASCII + superset). */ + PyErr_Format(PyExc_ValueError, + "Unknown conversion specifier %c", + (char)conversion); + } else + PyErr_Format(PyExc_ValueError, + "Unknown conversion specifier \\x%x", + (unsigned int)conversion); return NULL; } } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 29ca08c4bfc..fe49ec8dbe4 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -8895,7 +8895,7 @@ PyObject *PyUnicode_Format(PyObject *format, if (!isnumok) { PyErr_Format(PyExc_TypeError, "%%%c format: a number is required, " - "not %.200s", c, Py_TYPE(v)->tp_name); + "not %.200s", (char)c, Py_TYPE(v)->tp_name); goto onError; } if (flags & F_ZERO)