]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-129173: Use `_PyUnicodeError_GetParams` in `PyCodec_IgnoreErrors` (#129174)
authorBénédikt Tran <10796600+picnixz@users.noreply.github.com>
Fri, 24 Jan 2025 10:25:03 +0000 (11:25 +0100)
committerGitHub <noreply@github.com>
Fri, 24 Jan 2025 10:25:03 +0000 (11:25 +0100)
We also cleanup `PyCodec_StrictErrors` and the error message rendered
when an object of incorrect type is passed to codec error handlers.

Python/codecs.c

index 07eaa8ecddcae0c42a5ad5920892137ce3439494..53680a79082634a330403efed022052880596aac 100644 (file)
@@ -659,44 +659,64 @@ PyObject *PyCodec_LookupError(const char *name)
     return handler;
 }
 
-static void wrong_exception_type(PyObject *exc)
+
+static inline void
+wrong_exception_type(PyObject *exc)
 {
     PyErr_Format(PyExc_TypeError,
-                 "don't know how to handle %.200s in error callback",
-                 Py_TYPE(exc)->tp_name);
+                 "don't know how to handle %T in error callback", exc);
 }
 
+
+#define _PyIsUnicodeEncodeError(EXC)    \
+    PyObject_TypeCheck(EXC, (PyTypeObject *)PyExc_UnicodeEncodeError)
+#define _PyIsUnicodeDecodeError(EXC)    \
+    PyObject_TypeCheck(EXC, (PyTypeObject *)PyExc_UnicodeDecodeError)
+#define _PyIsUnicodeTranslateError(EXC) \
+    PyObject_TypeCheck(EXC, (PyTypeObject *)PyExc_UnicodeTranslateError)
+
+
+// --- handler: 'strict' ------------------------------------------------------
+
 PyObject *PyCodec_StrictErrors(PyObject *exc)
 {
-    if (PyExceptionInstance_Check(exc))
+    if (PyExceptionInstance_Check(exc)) {
         PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
-    else
+    }
+    else {
         PyErr_SetString(PyExc_TypeError, "codec must pass exception instance");
+    }
     return NULL;
 }
 
 
-PyObject *PyCodec_IgnoreErrors(PyObject *exc)
+// --- handler: 'ignore' ------------------------------------------------------
+
+static PyObject *
+_PyCodec_IgnoreError(PyObject *exc, int as_bytes)
 {
     Py_ssize_t end;
-
-    if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
-        if (PyUnicodeEncodeError_GetEnd(exc, &end))
-            return NULL;
+    if (_PyUnicodeError_GetParams(exc, NULL, NULL, NULL,
+                                  &end, NULL, as_bytes) < 0)
+    {
+        return NULL;
     }
-    else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) {
-        if (PyUnicodeDecodeError_GetEnd(exc, &end))
-            return NULL;
+    return Py_BuildValue("(Nn)", Py_GetConstant(Py_CONSTANT_EMPTY_STR), end);
+}
+
+
+PyObject *PyCodec_IgnoreErrors(PyObject *exc)
+{
+    if (_PyIsUnicodeEncodeError(exc) || _PyIsUnicodeTranslateError(exc)) {
+        return _PyCodec_IgnoreError(exc, false);
     }
-    else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) {
-        if (PyUnicodeTranslateError_GetEnd(exc, &end))
-            return NULL;
+    else if (_PyIsUnicodeDecodeError(exc)) {
+        return _PyCodec_IgnoreError(exc, true);
     }
     else {
         wrong_exception_type(exc);
         return NULL;
     }
-    return Py_BuildValue("(Nn)", Py_GetConstant(Py_CONSTANT_EMPTY_STR), end);
 }
 
 
@@ -1368,13 +1388,17 @@ PyCodec_SurrogateEscapeErrors(PyObject *exc)
 }
 
 
-static PyObject *strict_errors(PyObject *self, PyObject *exc)
+// --- Codecs registry handlers -----------------------------------------------
+
+static inline PyObject *
+strict_errors(PyObject *Py_UNUSED(self), PyObject *exc)
 {
     return PyCodec_StrictErrors(exc);
 }
 
 
-static PyObject *ignore_errors(PyObject *self, PyObject *exc)
+static inline PyObject *
+ignore_errors(PyObject *Py_UNUSED(self), PyObject *exc)
 {
     return PyCodec_IgnoreErrors(exc);
 }