mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
Close #20404: blacklist non-text encodings in io.TextIOWrapper
- io.TextIOWrapper (and hence the open() builtin) now use the internal codec marking system added for issue #19619 - also tweaked the C code to only look up the encoding once, rather than multiple times - the existing output type checks remain in place to deal with unmarked third party codecs.
This commit is contained in:
parent
1ea4e4174b
commit
a9b15241c6
6 changed files with 141 additions and 41 deletions
|
@ -849,7 +849,7 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds)
|
|||
char *kwlist[] = {"buffer", "encoding", "errors",
|
||||
"newline", "line_buffering", "write_through",
|
||||
NULL};
|
||||
PyObject *buffer, *raw;
|
||||
PyObject *buffer, *raw, *codec_info = NULL;
|
||||
char *encoding = NULL;
|
||||
char *errors = NULL;
|
||||
char *newline = NULL;
|
||||
|
@ -961,6 +961,17 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds)
|
|||
"could not determine default encoding");
|
||||
}
|
||||
|
||||
/* Check we have been asked for a real text encoding */
|
||||
codec_info = _PyCodec_LookupTextEncoding(encoding, "codecs.open()");
|
||||
if (codec_info == NULL) {
|
||||
Py_CLEAR(self->encoding);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* XXX: Failures beyond this point have the potential to leak elements
|
||||
* of the partially constructed object (like self->encoding)
|
||||
*/
|
||||
|
||||
if (errors == NULL)
|
||||
errors = "strict";
|
||||
self->errors = PyBytes_FromString(errors);
|
||||
|
@ -975,7 +986,7 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds)
|
|||
if (newline) {
|
||||
self->readnl = PyUnicode_FromString(newline);
|
||||
if (self->readnl == NULL)
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
self->writetranslate = (newline == NULL || newline[0] != '\0');
|
||||
if (!self->readuniversal && self->readnl) {
|
||||
|
@ -999,8 +1010,8 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds)
|
|||
if (r == -1)
|
||||
goto error;
|
||||
if (r == 1) {
|
||||
self->decoder = PyCodec_IncrementalDecoder(
|
||||
encoding, errors);
|
||||
self->decoder = _PyCodecInfo_GetIncrementalDecoder(codec_info,
|
||||
errors);
|
||||
if (self->decoder == NULL)
|
||||
goto error;
|
||||
|
||||
|
@ -1024,17 +1035,12 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds)
|
|||
if (r == -1)
|
||||
goto error;
|
||||
if (r == 1) {
|
||||
PyObject *ci;
|
||||
self->encoder = PyCodec_IncrementalEncoder(
|
||||
encoding, errors);
|
||||
self->encoder = _PyCodecInfo_GetIncrementalEncoder(codec_info,
|
||||
errors);
|
||||
if (self->encoder == NULL)
|
||||
goto error;
|
||||
/* Get the normalized named of the codec */
|
||||
ci = _PyCodec_Lookup(encoding);
|
||||
if (ci == NULL)
|
||||
goto error;
|
||||
res = _PyObject_GetAttrId(ci, &PyId_name);
|
||||
Py_DECREF(ci);
|
||||
res = _PyObject_GetAttrId(codec_info, &PyId_name);
|
||||
if (res == NULL) {
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError))
|
||||
PyErr_Clear();
|
||||
|
@ -1054,6 +1060,9 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds)
|
|||
Py_XDECREF(res);
|
||||
}
|
||||
|
||||
/* Finished sorting out the codec details */
|
||||
Py_DECREF(codec_info);
|
||||
|
||||
self->buffer = buffer;
|
||||
Py_INCREF(buffer);
|
||||
|
||||
|
@ -1116,6 +1125,7 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds)
|
|||
return 0;
|
||||
|
||||
error:
|
||||
Py_XDECREF(codec_info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue