mirror of
https://github.com/python/cpython.git
synced 2025-08-03 00:23:06 +00:00
bpo-37388: Development mode check encoding and errors (GH-14341)
In development mode and in debug build, encoding and errors arguments are now checked on string encoding and decoding operations. Examples: open(), str.encode() and bytes.decode(). By default, for best performances, the errors argument is only checked at the first encoding/decoding error, and the encoding argument is sometimes ignored for empty strings.
This commit is contained in:
parent
e1a63c4f21
commit
22eb689cf3
10 changed files with 315 additions and 6 deletions
|
@ -988,6 +988,46 @@ _textiowrapper_fix_encoder_state(textio *self)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
io_check_errors(PyObject *errors)
|
||||
{
|
||||
assert(errors != NULL && errors != Py_None);
|
||||
|
||||
PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
|
||||
#ifndef Py_DEBUG
|
||||
/* In release mode, only check in development mode (-X dev) */
|
||||
if (!interp->config.dev_mode) {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
/* Always check in debug mode */
|
||||
#endif
|
||||
|
||||
/* Avoid calling PyCodec_LookupError() before the codec registry is ready:
|
||||
before_PyUnicode_InitEncodings() is called. */
|
||||
if (!interp->fs_codec.encoding) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py_ssize_t name_length;
|
||||
const char *name = PyUnicode_AsUTF8AndSize(errors, &name_length);
|
||||
if (name == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (strlen(name) != (size_t)name_length) {
|
||||
PyErr_SetString(PyExc_ValueError, "embedded null character in errors");
|
||||
return -1;
|
||||
}
|
||||
PyObject *handler = PyCodec_LookupError(name);
|
||||
if (handler != NULL) {
|
||||
Py_DECREF(handler);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
_io.TextIOWrapper.__init__
|
||||
buffer: object
|
||||
|
@ -1057,6 +1097,9 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
|
|||
errors->ob_type->tp_name);
|
||||
return -1;
|
||||
}
|
||||
else if (io_check_errors(errors)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (validate_newline(newline) < 0) {
|
||||
return -1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue