From bd07ea405ab750deb7d58b2d88c9195c72c33532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Fri, 6 Dec 2024 15:49:08 +0100 Subject: [PATCH 01/13] add type checks when using `PyUnicodeError` objects --- Objects/exceptions.c | 208 +++++++++++++++++++++++++++++-------------- 1 file changed, 140 insertions(+), 68 deletions(-) diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 124b591ee3a13f..20fb836e47fa03 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2668,7 +2668,7 @@ SimpleExtendsException(PyExc_ValueError, UnicodeError, "Unicode related error."); static PyObject * -get_string(PyObject *attr, const char *name) +get_bytes(PyObject *attr, const char *name) { if (!attr) { PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name); @@ -2748,40 +2748,65 @@ unicode_error_adjust_end(Py_ssize_t end, Py_ssize_t objlen) return end; } +#define _PyUnicodeError_CAST(PTR) _Py_CAST(PyUnicodeErrorObject *, PTR) +#define PyUnicodeError_Check(PTR) \ + PyObject_TypeCheck((PTR), (PyTypeObject *)&PyExc_UnicodeError) +#define PyUnicodeError_CAST(PTR) \ + (assert(PyUnicodeError_Check(PTR)), _PyUnicodeError_CAST(PTR)) + +static inline PyUnicodeErrorObject * +as_unicode_error(PyObject *self, const char *expect_type) +{ + if (!PyUnicodeError_Check(self)) { + PyErr_Format(PyExc_TypeError, + "expecting a %s object, got %T", expect_type, self); + return NULL; + } + return _PyUnicodeError_CAST(self); +} + PyObject * -PyUnicodeEncodeError_GetEncoding(PyObject *exc) +PyUnicodeEncodeError_GetEncoding(PyObject *self) { - return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding"); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeEncodeError"); + return exc == NULL ? NULL : get_unicode(exc->encoding, "encoding"); } PyObject * -PyUnicodeDecodeError_GetEncoding(PyObject *exc) +PyUnicodeDecodeError_GetEncoding(PyObject *self) { - return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding"); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeDecodeError"); + return exc == NULL ? NULL : get_unicode(exc->encoding, "encoding"); } PyObject * -PyUnicodeEncodeError_GetObject(PyObject *exc) +PyUnicodeEncodeError_GetObject(PyObject *self) { - return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object"); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeEncodeError"); + return exc == NULL ? NULL : get_unicode(exc->encoding, "object"); } PyObject * -PyUnicodeDecodeError_GetObject(PyObject *exc) +PyUnicodeDecodeError_GetObject(PyObject *self) { - return get_string(((PyUnicodeErrorObject *)exc)->object, "object"); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeDecodeError"); + return exc == NULL ? NULL : get_bytes(exc->encoding, "object"); } PyObject * -PyUnicodeTranslateError_GetObject(PyObject *exc) +PyUnicodeTranslateError_GetObject(PyObject *self) { - return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object"); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeTranslateError"); + return exc == NULL ? NULL : get_unicode(exc->encoding, "object"); } int PyUnicodeEncodeError_GetStart(PyObject *self, Py_ssize_t *start) { - PyUnicodeErrorObject *exc = (PyUnicodeErrorObject *)self; + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeEncodeError"); + if (exc == NULL) { + return -1; + } PyObject *obj = get_unicode(exc->object, "object"); if (obj == NULL) { return -1; @@ -2796,8 +2821,11 @@ PyUnicodeEncodeError_GetStart(PyObject *self, Py_ssize_t *start) int PyUnicodeDecodeError_GetStart(PyObject *self, Py_ssize_t *start) { - PyUnicodeErrorObject *exc = (PyUnicodeErrorObject *)self; - PyObject *obj = get_string(exc->object, "object"); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeDecodeError"); + if (exc == NULL) { + return -1; + } + PyObject *obj = get_bytes(exc->object, "object"); if (obj == NULL) { return -1; } @@ -2809,45 +2837,63 @@ PyUnicodeDecodeError_GetStart(PyObject *self, Py_ssize_t *start) int -PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start) +PyUnicodeTranslateError_GetStart(PyObject *self, Py_ssize_t *start) { - return PyUnicodeEncodeError_GetStart(exc, start); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeTranslateError"); + if (exc == NULL) { + return -1; + } + PyObject *obj = get_unicode(exc->object, "object"); + if (obj == NULL) { + return -1; + } + Py_ssize_t size = PyUnicode_GET_LENGTH(obj); + Py_DECREF(obj); + *start = unicode_error_adjust_start(exc->start, size); + return 0; } static inline int unicode_error_set_start_impl(PyObject *self, Py_ssize_t start) { - ((PyUnicodeErrorObject *)self)->start = start; + PyUnicodeErrorObject *exc = _PyUnicodeError_CAST(self); + exc->start = start; return 0; } int -PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start) +PyUnicodeEncodeError_SetStart(PyObject *self, Py_ssize_t start) { - return unicode_error_set_start_impl(exc, start); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeEncodeError"); + return exc == NULL ? -1 : unicode_error_set_start_impl(self, start); } int -PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start) +PyUnicodeDecodeError_SetStart(PyObject *self, Py_ssize_t start) { - return unicode_error_set_start_impl(exc, start); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeDecodeError"); + return exc == NULL ? -1 : unicode_error_set_start_impl(self, start); } int -PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start) +PyUnicodeTranslateError_SetStart(PyObject *self, Py_ssize_t start) { - return unicode_error_set_start_impl(exc, start); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeTranslateError"); + return exc == NULL ? -1 : unicode_error_set_start_impl(self, start); } int PyUnicodeEncodeError_GetEnd(PyObject *self, Py_ssize_t *end) { - PyUnicodeErrorObject *exc = (PyUnicodeErrorObject *)self; + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeEncodeError"); + if (exc == NULL) { + return -1; + } PyObject *obj = get_unicode(exc->object, "object"); if (obj == NULL) { return -1; @@ -2862,8 +2908,11 @@ PyUnicodeEncodeError_GetEnd(PyObject *self, Py_ssize_t *end) int PyUnicodeDecodeError_GetEnd(PyObject *self, Py_ssize_t *end) { - PyUnicodeErrorObject *exc = (PyUnicodeErrorObject *)self; - PyObject *obj = get_string(exc->object, "object"); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeDecodeError"); + if (exc == NULL) { + return -1; + } + PyObject *obj = get_bytes(exc->object, "object"); if (obj == NULL) { return -1; } @@ -2875,108 +2924,131 @@ PyUnicodeDecodeError_GetEnd(PyObject *self, Py_ssize_t *end) int -PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end) +PyUnicodeTranslateError_GetEnd(PyObject *self, Py_ssize_t *end) { - return PyUnicodeEncodeError_GetEnd(exc, end); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeTranslateError"); + if (exc == NULL) { + return -1; + } + PyObject *obj = get_unicode(exc->object, "object"); + if (obj == NULL) { + return -1; + } + Py_ssize_t size = PyUnicode_GET_LENGTH(obj); + Py_DECREF(obj); + *end = unicode_error_adjust_end(exc->end, size); + return 0; } static inline int -unicode_error_set_end_impl(PyObject *exc, Py_ssize_t end) +unicode_error_set_end_impl(PyObject *self, Py_ssize_t end) { - ((PyUnicodeErrorObject *)exc)->end = end; + PyUnicodeErrorObject *exc = _PyUnicodeError_CAST(self); + exc->end = end; return 0; } int -PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end) +PyUnicodeEncodeError_SetEnd(PyObject *self, Py_ssize_t end) { - return unicode_error_set_end_impl(exc, end); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeEncodeError"); + return exc == NULL ? -1 : unicode_error_set_end_impl(self, end); } int -PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end) +PyUnicodeDecodeError_SetEnd(PyObject *self, Py_ssize_t end) { - return unicode_error_set_end_impl(exc, end); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeDecodeError"); + return exc == NULL ? -1 : unicode_error_set_end_impl(self, end); } int -PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end) +PyUnicodeTranslateError_SetEnd(PyObject *self, Py_ssize_t end) { - return unicode_error_set_end_impl(exc, end); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeTranslateError"); + return exc == NULL ? -1 : unicode_error_set_end_impl(self, end); } + PyObject * -PyUnicodeEncodeError_GetReason(PyObject *exc) +PyUnicodeEncodeError_GetReason(PyObject *self) { - return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason"); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeEncodeError"); + return exc == NULL ? NULL : get_unicode(exc->reason, "reason"); } PyObject * -PyUnicodeDecodeError_GetReason(PyObject *exc) +PyUnicodeDecodeError_GetReason(PyObject *self) { - return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason"); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeDecodeError"); + return exc == NULL ? NULL : get_unicode(exc->reason, "reason"); } PyObject * -PyUnicodeTranslateError_GetReason(PyObject *exc) +PyUnicodeTranslateError_GetReason(PyObject *self) { - return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason"); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeTranslateError"); + return exc == NULL ? NULL : get_unicode(exc->reason, "reason"); } int -PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason) +PyUnicodeEncodeError_SetReason(PyObject *self, const char *reason) { - return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason, - reason); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeEncodeError"); + return exc == NULL ? -1 : set_unicodefromstring(&exc->reason, reason); } int -PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason) +PyUnicodeDecodeError_SetReason(PyObject *self, const char *reason) { - return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason, - reason); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeDecodeError"); + return exc == NULL ? -1 : set_unicodefromstring(&exc->reason, reason); } int -PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason) +PyUnicodeTranslateError_SetReason(PyObject *self, const char *reason) { - return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason, - reason); + PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeTranslateError"); + return exc == NULL ? -1 : set_unicodefromstring(&exc->reason, reason); } static int -UnicodeError_clear(PyUnicodeErrorObject *self) +UnicodeError_clear(PyObject *self) { - Py_CLEAR(self->encoding); - Py_CLEAR(self->object); - Py_CLEAR(self->reason); + PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self); + Py_CLEAR(exc->encoding); + Py_CLEAR(exc->object); + Py_CLEAR(exc->reason); return BaseException_clear((PyBaseExceptionObject *)self); } static void -UnicodeError_dealloc(PyUnicodeErrorObject *self) +UnicodeError_dealloc(PyObject *self) { + PyTypeObject *type = Py_TYPE(self); _PyObject_GC_UNTRACK(self); - UnicodeError_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); + (void)UnicodeError_clear(self); + type->tp_free(self); + // TODO: should we decref type here? } static int -UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg) +UnicodeError_traverse(PyObject *self, visitproc visit, void *arg) { - Py_VISIT(self->encoding); - Py_VISIT(self->object); - Py_VISIT(self->reason); + PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self); + Py_VISIT(exc->encoding); + Py_VISIT(exc->object); + Py_VISIT(exc->reason); return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); } @@ -3015,7 +3087,7 @@ UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; } - PyUnicodeErrorObject *exc = (PyUnicodeErrorObject *)self; + PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self); Py_XSETREF(exc->encoding, Py_NewRef(encoding)); Py_XSETREF(exc->object, Py_NewRef(object)); exc->start = start; @@ -3027,7 +3099,7 @@ UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds) static PyObject * UnicodeEncodeError_str(PyObject *self) { - PyUnicodeErrorObject *exc = (PyUnicodeErrorObject *)self; + PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self); PyObject *result = NULL; PyObject *reason_str = NULL; PyObject *encoding_str = NULL; @@ -3135,7 +3207,7 @@ UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds) } } - PyUnicodeErrorObject *exc = (PyUnicodeErrorObject *)self; + PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self); Py_XSETREF(exc->encoding, Py_NewRef(encoding)); Py_XSETREF(exc->object, object /* already a strong reference */); exc->start = start; @@ -3147,7 +3219,7 @@ UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds) static PyObject * UnicodeDecodeError_str(PyObject *self) { - PyUnicodeErrorObject *exc = (PyUnicodeErrorObject *)self; + PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self); PyObject *result = NULL; PyObject *reason_str = NULL; PyObject *encoding_str = NULL; @@ -3236,7 +3308,7 @@ UnicodeTranslateError_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; } - PyUnicodeErrorObject *exc = (PyUnicodeErrorObject *)self; + PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self); Py_XSETREF(exc->object, Py_NewRef(object)); exc->start = start; exc->end = end; @@ -3248,7 +3320,7 @@ UnicodeTranslateError_init(PyObject *self, PyObject *args, PyObject *kwds) static PyObject * UnicodeTranslateError_str(PyObject *self) { - PyUnicodeErrorObject *exc = (PyUnicodeErrorObject *)self; + PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self); PyObject *result = NULL; PyObject *reason_str = NULL; From 21bcef2b3746327e1757b09c0fd2e24fd0a7115d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Fri, 6 Dec 2024 15:53:38 +0100 Subject: [PATCH 02/13] reduce un-necessary casts --- Objects/exceptions.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 20fb836e47fa03..361a234b17223a 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2754,6 +2754,19 @@ unicode_error_adjust_end(Py_ssize_t end, Py_ssize_t objlen) #define PyUnicodeError_CAST(PTR) \ (assert(PyUnicodeError_Check(PTR)), _PyUnicodeError_CAST(PTR)) + +static inline int +check_unicode_error_type(PyObject *self, const char *expect_type) +{ + if (!PyUnicodeError_Check(self)) { + PyErr_Format(PyExc_TypeError, + "expecting a %s object, got %T", expect_type, self); + return -1; + } + return 0; +} + + static inline PyUnicodeErrorObject * as_unicode_error(PyObject *self, const char *expect_type) { @@ -2866,24 +2879,24 @@ unicode_error_set_start_impl(PyObject *self, Py_ssize_t start) int PyUnicodeEncodeError_SetStart(PyObject *self, Py_ssize_t start) { - PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeEncodeError"); - return exc == NULL ? -1 : unicode_error_set_start_impl(self, start); + int rc = check_unicode_error_type(self, "UnicodeEncodeError"); + return rc < 0 ? -1 : unicode_error_set_start_impl(self, start); } int PyUnicodeDecodeError_SetStart(PyObject *self, Py_ssize_t start) { - PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeDecodeError"); - return exc == NULL ? -1 : unicode_error_set_start_impl(self, start); + int rc = check_unicode_error_type(self, "UnicodeDecodeError"); + return rc < 0 ? -1 : unicode_error_set_start_impl(self, start); } int PyUnicodeTranslateError_SetStart(PyObject *self, Py_ssize_t start) { - PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeTranslateError"); - return exc == NULL ? -1 : unicode_error_set_start_impl(self, start); + int rc = check_unicode_error_type(self, "UnicodeTranslateError"); + return rc < 0 ? -1 : unicode_error_set_start_impl(self, start); } @@ -2953,24 +2966,24 @@ unicode_error_set_end_impl(PyObject *self, Py_ssize_t end) int PyUnicodeEncodeError_SetEnd(PyObject *self, Py_ssize_t end) { - PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeEncodeError"); - return exc == NULL ? -1 : unicode_error_set_end_impl(self, end); + int rc = check_unicode_error_type(self, "UnicodeEncodeError"); + return rc < 0 ? -1 : unicode_error_set_end_impl(self, end); } int PyUnicodeDecodeError_SetEnd(PyObject *self, Py_ssize_t end) { - PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeDecodeError"); - return exc == NULL ? -1 : unicode_error_set_end_impl(self, end); + int rc = check_unicode_error_type(self, "UnicodeDecodeError"); + return rc < 0 ? -1 : unicode_error_set_end_impl(self, end); } int PyUnicodeTranslateError_SetEnd(PyObject *self, Py_ssize_t end) { - PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeTranslateError"); - return exc == NULL ? -1 : unicode_error_set_end_impl(self, end); + int rc = check_unicode_error_type(self, "UnicodeTranslateError"); + return rc < 0 ? -1 : unicode_error_set_end_impl(self, end); } From 17d26655d13448120c5662c0c34ddc305712929f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:42:49 +0100 Subject: [PATCH 03/13] fix check --- Objects/exceptions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 361a234b17223a..945e003a79cbaa 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2750,7 +2750,7 @@ unicode_error_adjust_end(Py_ssize_t end, Py_ssize_t objlen) #define _PyUnicodeError_CAST(PTR) _Py_CAST(PyUnicodeErrorObject *, PTR) #define PyUnicodeError_Check(PTR) \ - PyObject_TypeCheck((PTR), (PyTypeObject *)&PyExc_UnicodeError) + PyObject_TypeCheck((PTR), (PyTypeObject *)PyExc_UnicodeError) #define PyUnicodeError_CAST(PTR) \ (assert(PyUnicodeError_Check(PTR)), _PyUnicodeError_CAST(PTR)) From bac503166e27881c546b58e34b71e1b45f5f7534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:48:11 +0100 Subject: [PATCH 04/13] fix tests --- Objects/exceptions.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 945e003a79cbaa..3a5b1187c63bff 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2796,21 +2796,21 @@ PyObject * PyUnicodeEncodeError_GetObject(PyObject *self) { PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeEncodeError"); - return exc == NULL ? NULL : get_unicode(exc->encoding, "object"); + return exc == NULL ? NULL : get_unicode(exc->object, "object"); } PyObject * PyUnicodeDecodeError_GetObject(PyObject *self) { PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeDecodeError"); - return exc == NULL ? NULL : get_bytes(exc->encoding, "object"); + return exc == NULL ? NULL : get_bytes(exc->object, "object"); } PyObject * PyUnicodeTranslateError_GetObject(PyObject *self) { PyUnicodeErrorObject *exc = as_unicode_error(self, "UnicodeTranslateError"); - return exc == NULL ? NULL : get_unicode(exc->encoding, "object"); + return exc == NULL ? NULL : get_unicode(exc->object, "object"); } int From 37655a2617c7eac33237139717bca1b7232a5ac3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:54:10 +0100 Subject: [PATCH 05/13] blurb --- Doc/whatsnew/3.14.rst | 6 ++++++ .../C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst | 3 +++ 2 files changed, 9 insertions(+) create mode 100644 Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index b300e348679438..4cd50d0794128c 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -1027,6 +1027,12 @@ New features * Add :c:func:`PyUnstable_Object_EnableDeferredRefcount` for enabling deferred reference counting, as outlined in :pep:`703`. +* The :ref:`Unicode Exceptions Objects ` C API + now type-checks its exception argument, raising a :exc:`TypeError` if the + latter is not an instance of :exc:`UnicodeError`. + (Contributed by Bénédikt Tran in :gh:`127691`.) + + Porting to Python 3.14 ---------------------- diff --git a/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst b/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst new file mode 100644 index 00000000000000..bf22c8dc9e6ccf --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst @@ -0,0 +1,3 @@ +The :ref:`Unicode Exceptions Objects ` C API now +type-checks its exception argument, raising a :exc:`TypeError` if the latter +is not an instance of :exc:`UnicodeError`. Patch by Bénédikt Tran. From af7e7bbe3e21f8d58c11d2452f6203fbed7ccf38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:57:08 +0100 Subject: [PATCH 06/13] fix typo --- Doc/whatsnew/3.14.rst | 2 +- .../next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 4cd50d0794128c..540219a044a338 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -1027,7 +1027,7 @@ New features * Add :c:func:`PyUnstable_Object_EnableDeferredRefcount` for enabling deferred reference counting, as outlined in :pep:`703`. -* The :ref:`Unicode Exceptions Objects ` C API +* The :ref:`Unicode Exception Objects ` C API now type-checks its exception argument, raising a :exc:`TypeError` if the latter is not an instance of :exc:`UnicodeError`. (Contributed by Bénédikt Tran in :gh:`127691`.) diff --git a/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst b/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst index bf22c8dc9e6ccf..323df2ed58b7af 100644 --- a/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst +++ b/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst @@ -1,3 +1,3 @@ -The :ref:`Unicode Exceptions Objects ` C API now +The :ref:`Unicode Exception Objects ` C API now type-checks its exception argument, raising a :exc:`TypeError` if the latter is not an instance of :exc:`UnicodeError`. Patch by Bénédikt Tran. From a8bfd70aab48da831a3ae5fc5c497f2d04679d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Fri, 6 Dec 2024 17:06:04 +0100 Subject: [PATCH 07/13] fix refs --- Doc/whatsnew/3.14.rst | 6 +++--- .../C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 540219a044a338..7674fc9224d6de 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -1027,9 +1027,9 @@ New features * Add :c:func:`PyUnstable_Object_EnableDeferredRefcount` for enabling deferred reference counting, as outlined in :pep:`703`. -* The :ref:`Unicode Exception Objects ` C API - now type-checks its exception argument, raising a :exc:`TypeError` if the - latter is not an instance of :exc:`UnicodeError`. +* The :ref:`Unicode Exception Objects ` C API now + type-checks its exception argument, raising a :exc:`TypeError` if + the latter is not an instance of :exc:`UnicodeError`. (Contributed by Bénédikt Tran in :gh:`127691`.) diff --git a/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst b/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst index 323df2ed58b7af..235b13e6bb0220 100644 --- a/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst +++ b/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst @@ -1,3 +1,4 @@ -The :ref:`Unicode Exception Objects ` C API now -type-checks its exception argument, raising a :exc:`TypeError` if the latter -is not an instance of :exc:`UnicodeError`. Patch by Bénédikt Tran. +The :ref:`Unicode Exception Objects ` C API now +type-checks its exception argument, raising a :exc:`TypeError` if +the latter is not an instance of :exc:`UnicodeError`. +Patch by Bénédikt Tran. From 0ec814eea3c142c70ea2d09166625cafc61ed40f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 7 Dec 2024 17:59:37 +0100 Subject: [PATCH 08/13] Update CHANGELOG --- Doc/whatsnew/3.14.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 7674fc9224d6de..e176f1ab10ab90 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -1027,9 +1027,9 @@ New features * Add :c:func:`PyUnstable_Object_EnableDeferredRefcount` for enabling deferred reference counting, as outlined in :pep:`703`. -* The :ref:`Unicode Exception Objects ` C API now - type-checks its exception argument, raising a :exc:`TypeError` if - the latter is not an instance of :exc:`UnicodeError`. +* The :ref:`Unicode Exception Objects ` C API + now raises :exc:`TypeError` if its exception argument is not an + :exc:`UnicodeError`. (Contributed by Bénédikt Tran in :gh:`127691`.) From 7c7d20c2e67ea0c2f494802bd949ea40106077ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 7 Dec 2024 18:06:30 +0100 Subject: [PATCH 09/13] Apply suggestions from code review --- .../2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst | 7 +++---- Objects/exceptions.c | 11 +++-------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst b/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst index 235b13e6bb0220..93b25dd1d918bb 100644 --- a/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst +++ b/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst @@ -1,4 +1,3 @@ -The :ref:`Unicode Exception Objects ` C API now -type-checks its exception argument, raising a :exc:`TypeError` if -the latter is not an instance of :exc:`UnicodeError`. -Patch by Bénédikt Tran. +The :ref:`Unicode Exception Objects ` C API +now raises :exc:`TypeError` if its exception argument is not an +:exc:`UnicodeError`. Patch by Bénédikt Tran. diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 3a5b1187c63bff..a2a1e5db38234a 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2748,7 +2748,7 @@ unicode_error_adjust_end(Py_ssize_t end, Py_ssize_t objlen) return end; } -#define _PyUnicodeError_CAST(PTR) _Py_CAST(PyUnicodeErrorObject *, PTR) +#define _PyUnicodeError_CAST(PTR) ((PyUnicodeErrorObject *)(PTR)) #define PyUnicodeError_Check(PTR) \ PyObject_TypeCheck((PTR), (PyTypeObject *)PyExc_UnicodeError) #define PyUnicodeError_CAST(PTR) \ @@ -2770,12 +2770,8 @@ check_unicode_error_type(PyObject *self, const char *expect_type) static inline PyUnicodeErrorObject * as_unicode_error(PyObject *self, const char *expect_type) { - if (!PyUnicodeError_Check(self)) { - PyErr_Format(PyExc_TypeError, - "expecting a %s object, got %T", expect_type, self); - return NULL; - } - return _PyUnicodeError_CAST(self); + int rc = check_unicode_error_type(self, except_type); + return rc < 0 : NULL : _PyUnicodeError_CAST(self); } PyObject * @@ -3052,7 +3048,6 @@ UnicodeError_dealloc(PyObject *self) _PyObject_GC_UNTRACK(self); (void)UnicodeError_clear(self); type->tp_free(self); - // TODO: should we decref type here? } static int From 49a32cfa6eb85128376465a02b05b3d31dcc67b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 7 Dec 2024 18:17:14 +0100 Subject: [PATCH 10/13] Update Objects/exceptions.c --- Objects/exceptions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/exceptions.c b/Objects/exceptions.c index a2a1e5db38234a..9a3a5a13c2271f 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2770,7 +2770,7 @@ check_unicode_error_type(PyObject *self, const char *expect_type) static inline PyUnicodeErrorObject * as_unicode_error(PyObject *self, const char *expect_type) { - int rc = check_unicode_error_type(self, except_type); + int rc = check_unicode_error_type(self, expect_type); return rc < 0 : NULL : _PyUnicodeError_CAST(self); } From a5ee3d0c9eeaa46c3433aa8329bf575f44b7b883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 7 Dec 2024 18:21:39 +0100 Subject: [PATCH 11/13] Update Objects/exceptions.c --- Objects/exceptions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 9a3a5a13c2271f..2d3c43ffae7b51 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2771,7 +2771,7 @@ static inline PyUnicodeErrorObject * as_unicode_error(PyObject *self, const char *expect_type) { int rc = check_unicode_error_type(self, expect_type); - return rc < 0 : NULL : _PyUnicodeError_CAST(self); + return rc < 0 ? NULL : _PyUnicodeError_CAST(self); } PyObject * From 7fe6e6711d60145c0dbe83c85502f53474aa553e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 7 Dec 2024 19:19:34 +0100 Subject: [PATCH 12/13] Fix English --- Doc/whatsnew/3.14.rst | 2 +- .../next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index e176f1ab10ab90..206ce85b2b04eb 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -1028,7 +1028,7 @@ New features deferred reference counting, as outlined in :pep:`703`. * The :ref:`Unicode Exception Objects ` C API - now raises :exc:`TypeError` if its exception argument is not an + now raises a :exc:`TypeError` if its exception argument is not a :exc:`UnicodeError`. (Contributed by Bénédikt Tran in :gh:`127691`.) diff --git a/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst b/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst index 93b25dd1d918bb..90d1a51e672c7c 100644 --- a/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst +++ b/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst @@ -1,3 +1,3 @@ The :ref:`Unicode Exception Objects ` C API -now raises :exc:`TypeError` if its exception argument is not an +now raises a :exc:`TypeError` if its exception argument is not a :exc:`UnicodeError`. Patch by Bénédikt Tran. From 970720a526eac56fc1a8bff761546c847ebce286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 7 Dec 2024 19:20:33 +0100 Subject: [PATCH 13/13] Improve wording --- Doc/whatsnew/3.14.rst | 4 ++-- .../next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 206ce85b2b04eb..df7eb71bdd514d 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -1028,8 +1028,8 @@ New features deferred reference counting, as outlined in :pep:`703`. * The :ref:`Unicode Exception Objects ` C API - now raises a :exc:`TypeError` if its exception argument is not a - :exc:`UnicodeError`. + now raises a :exc:`TypeError` if its exception argument is not + a :exc:`UnicodeError` object. (Contributed by Bénédikt Tran in :gh:`127691`.) diff --git a/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst b/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst index 90d1a51e672c7c..c942ff3d9eda53 100644 --- a/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst +++ b/Misc/NEWS.d/next/C_API/2024-12-06-16-53-34.gh-issue-127691.k_Jitp.rst @@ -1,3 +1,3 @@ The :ref:`Unicode Exception Objects ` C API -now raises a :exc:`TypeError` if its exception argument is not a -:exc:`UnicodeError`. Patch by Bénédikt Tran. +now raises a :exc:`TypeError` if its exception argument is not +a :exc:`UnicodeError` object. Patch by Bénédikt Tran.