summaryrefslogtreecommitdiffstats
path: root/Python/codecs.c
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2014-02-04 12:11:18 (GMT)
committerNick Coghlan <ncoghlan@gmail.com>2014-02-04 12:11:18 (GMT)
commita9b15241c6bdf8ac71f1dc598b7c01a20518b6a7 (patch)
tree4a72ac89949ce222ffcad240b450913b0351e1ad /Python/codecs.c
parent1ea4e4174ba4051d74aedb9bdc0c020d88e3588c (diff)
downloadcpython-a9b15241c6bdf8ac71f1dc598b7c01a20518b6a7.zip
cpython-a9b15241c6bdf8ac71f1dc598b7c01a20518b6a7.tar.gz
cpython-a9b15241c6bdf8ac71f1dc598b7c01a20518b6a7.tar.bz2
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.
Diffstat (limited to 'Python/codecs.c')
-rw-r--r--Python/codecs.c84
1 files changed, 63 insertions, 21 deletions
diff --git a/Python/codecs.c b/Python/codecs.c
index 5ff41b5..e06d6e0 100644
--- a/Python/codecs.c
+++ b/Python/codecs.c
@@ -243,20 +243,15 @@ PyObject *codec_getitem(const char *encoding, int index)
return v;
}
-/* Helper function to create an incremental codec. */
-
+/* Helper functions to create an incremental codec. */
static
-PyObject *codec_getincrementalcodec(const char *encoding,
- const char *errors,
- const char *attrname)
+PyObject *codec_makeincrementalcodec(PyObject *codec_info,
+ const char *errors,
+ const char *attrname)
{
- PyObject *codecs, *ret, *inccodec;
+ PyObject *ret, *inccodec;
- codecs = _PyCodec_Lookup(encoding);
- if (codecs == NULL)
- return NULL;
- inccodec = PyObject_GetAttrString(codecs, attrname);
- Py_DECREF(codecs);
+ inccodec = PyObject_GetAttrString(codec_info, attrname);
if (inccodec == NULL)
return NULL;
if (errors)
@@ -267,6 +262,21 @@ PyObject *codec_getincrementalcodec(const char *encoding,
return ret;
}
+static
+PyObject *codec_getincrementalcodec(const char *encoding,
+ const char *errors,
+ const char *attrname)
+{
+ PyObject *codec_info, *ret;
+
+ codec_info = _PyCodec_Lookup(encoding);
+ if (codec_info == NULL)
+ return NULL;
+ ret = codec_makeincrementalcodec(codec_info, errors, attrname);
+ Py_DECREF(codec_info);
+ return ret;
+}
+
/* Helper function to create a stream codec. */
static
@@ -290,6 +300,24 @@ PyObject *codec_getstreamcodec(const char *encoding,
return streamcodec;
}
+/* Helpers to work with the result of _PyCodec_Lookup
+
+ */
+PyObject *_PyCodecInfo_GetIncrementalDecoder(PyObject *codec_info,
+ const char *errors)
+{
+ return codec_makeincrementalcodec(codec_info, errors,
+ "incrementaldecoder");
+}
+
+PyObject *_PyCodecInfo_GetIncrementalEncoder(PyObject *codec_info,
+ const char *errors)
+{
+ return codec_makeincrementalcodec(codec_info, errors,
+ "incrementalencoder");
+}
+
+
/* Convenience APIs to query the Codec registry.
All APIs return a codec object with incremented refcount.
@@ -467,15 +495,12 @@ PyObject *PyCodec_Decode(PyObject *object,
}
/* Text encoding/decoding API */
-static
-PyObject *codec_getitem_checked(const char *encoding,
- const char *operation_name,
- int index)
+PyObject * _PyCodec_LookupTextEncoding(const char *encoding,
+ const char *alternate_command)
{
_Py_IDENTIFIER(_is_text_encoding);
PyObject *codec;
PyObject *attr;
- PyObject *v;
int is_text_codec;
codec = _PyCodec_Lookup(encoding);
@@ -502,27 +527,44 @@ PyObject *codec_getitem_checked(const char *encoding,
Py_DECREF(codec);
PyErr_Format(PyExc_LookupError,
"'%.400s' is not a text encoding; "
- "use codecs.%s() to handle arbitrary codecs",
- encoding, operation_name);
+ "use %s to handle arbitrary codecs",
+ encoding, alternate_command);
return NULL;
}
}
}
+ /* This appears to be a valid text encoding */
+ return codec;
+}
+
+
+static
+PyObject *codec_getitem_checked(const char *encoding,
+ const char *alternate_command,
+ int index)
+{
+ PyObject *codec;
+ PyObject *v;
+
+ codec = _PyCodec_LookupTextEncoding(encoding, alternate_command);
+ if (codec == NULL)
+ return NULL;
+
v = PyTuple_GET_ITEM(codec, index);
- Py_DECREF(codec);
Py_INCREF(v);
+ Py_DECREF(codec);
return v;
}
static PyObject * _PyCodec_TextEncoder(const char *encoding)
{
- return codec_getitem_checked(encoding, "encode", 0);
+ return codec_getitem_checked(encoding, "codecs.encode()", 0);
}
static PyObject * _PyCodec_TextDecoder(const char *encoding)
{
- return codec_getitem_checked(encoding, "decode", 1);
+ return codec_getitem_checked(encoding, "codecs.decode()", 1);
}
PyObject *_PyCodec_EncodeText(PyObject *object,