From ba32cfd7a414956ce498c5eb9677a507dc8aa5fb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 24 Mar 2025 15:09:48 +0100 Subject: [PATCH 1/2] gh-111178: Fix function signature in pyexpat.c Move _Py_NO_SANITIZE_UNDEFINED macro from faulthandler.c to pyport.h. --- Include/pyport.h | 20 +++++++++++++++++++ Modules/faulthandler.c | 17 ---------------- Modules/pyexpat.c | 45 +++++++++++++++++++++++++++--------------- 3 files changed, 49 insertions(+), 33 deletions(-) diff --git a/Include/pyport.h b/Include/pyport.h index e7162f4d9bf6b0..2a7192c2c55cdd 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -655,4 +655,24 @@ extern "C" { # define _Py_FALLTHROUGH do { } while (0) #endif + +// _Py_NO_SANITIZE_UNDEFINED(): Disable Undefined Behavior sanitizer (UBsan) +// on a function. +// +// Clang and GCC 9.0+ use __attribute__((no_sanitize("undefined"))). +// GCC 4.9+ uses __attribute__((no_sanitize_undefined)). +#if defined(__has_feature) +# if __has_feature(undefined_behavior_sanitizer) +# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"))) +# endif +#endif +#if !defined(_Py_NO_SANITIZE_UNDEFINED) && defined(__GNUC__) \ + && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) +# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined)) +#endif +#ifndef _Py_NO_SANITIZE_UNDEFINED +# define _Py_NO_SANITIZE_UNDEFINED +#endif + + #endif /* Py_PYPORT_H */ diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 3b87864e1f2566..ba7970d66565e5 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -40,23 +40,6 @@ #define PUTS(fd, str) (void)_Py_write_noraise(fd, str, strlen(str)) -// Clang and GCC 9.0+ use __attribute__((no_sanitize("undefined"))) -#if defined(__has_feature) -# if __has_feature(undefined_behavior_sanitizer) -# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"))) -# endif -#endif - -// GCC 4.9+ uses __attribute__((no_sanitize_undefined)) -#if !defined(_Py_NO_SANITIZE_UNDEFINED) && defined(__GNUC__) \ - && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) -# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined)) -#endif -#ifndef _Py_NO_SANITIZE_UNDEFINED -# define _Py_NO_SANITIZE_UNDEFINED -#endif - - typedef struct { int signum; int enabled; diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 1ba644d3396f7f..bfddc30edfd648 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -110,11 +110,15 @@ struct HandlerInfo { static struct HandlerInfo handler_info[64]; -#define CALL_XML_HANDLER_SETTER(HANDLER_INFO, XML_PARSER, XML_HANDLER) \ - do { \ - xmlhandlersetter setter = (xmlhandlersetter)(HANDLER_INFO).setter; \ - setter((XML_PARSER), (XML_HANDLER)); \ - } while (0) +// gh-111178: Use _Py_NO_SANITIZE_UNDEFINED, rather than using the exact +// handler API for each handler. +static inline void _Py_NO_SANITIZE_UNDEFINED +CALL_XML_HANDLER_SETTER(const struct HandlerInfo *handler_info, + XML_Parser xml_parser, xmlhandler xml_handler) +{ + xmlhandlersetter setter = (xmlhandlersetter)(handler_info->setter); + setter(xml_parser, xml_handler); +} /* Set an integer attribute on the error object; return true on success, * false on an exception. @@ -182,6 +186,12 @@ conv_string_to_unicode(const XML_Char *str) return PyUnicode_DecodeUTF8(str, strlen(str), "strict"); } +static PyObject * +conv_string_to_unicode_void(void *arg) +{ + return conv_string_to_unicode((const XML_Char *)arg); +} + static PyObject * conv_string_len_to_unicode(const XML_Char *str, int len) { @@ -498,7 +508,7 @@ VOID_HANDLER(ProcessingInstruction, (void *userData, const XML_Char *target, const XML_Char *data), - ("(NO&)", string_intern(self, target), conv_string_to_unicode ,data)) + ("(NO&)", string_intern(self, target), conv_string_to_unicode_void, data)) VOID_HANDLER(UnparsedEntityDecl, (void *userData, @@ -535,12 +545,13 @@ VOID_HANDLER(XmlDecl, const XML_Char *encoding, int standalone), ("(O&O&i)", - conv_string_to_unicode ,version, conv_string_to_unicode ,encoding, + conv_string_to_unicode_void, version, + conv_string_to_unicode_void, encoding, standalone)) static PyObject * conv_content_model(XML_Content * const model, - PyObject *(*conv_string)(const XML_Char *)) + PyObject *(*conv_string)(void *)) { PyObject *result = NULL; PyObject *children = PyTuple_New(model->numchildren); @@ -559,7 +570,7 @@ conv_content_model(XML_Content * const model, } result = Py_BuildValue("(iiO&N)", model->type, model->quant, - conv_string,model->name, children); + conv_string, model->name, children); } return result; } @@ -581,7 +592,7 @@ my_ElementDeclHandler(void *userData, if (flush_character_buffer(self) < 0) goto finally; - modelobj = conv_content_model(model, (conv_string_to_unicode)); + modelobj = conv_content_model(model, (conv_string_to_unicode_void)); if (modelobj == NULL) { flag_error(self); goto finally; @@ -622,7 +633,8 @@ VOID_HANDLER(AttlistDecl, int isrequired), ("(NNO&O&i)", string_intern(self, elname), string_intern(self, attname), - conv_string_to_unicode ,att_type, conv_string_to_unicode ,dflt, + conv_string_to_unicode_void, att_type, + conv_string_to_unicode_void, dflt, isrequired)) #if XML_COMBINED_VERSION >= 19504 @@ -658,7 +670,7 @@ VOID_HANDLER(EndNamespaceDecl, VOID_HANDLER(Comment, (void *userData, const XML_Char *data), - ("(O&)", conv_string_to_unicode ,data)) + ("(O&)", conv_string_to_unicode_void, data)) VOID_HANDLER(StartCdataSection, (void *userData), @@ -689,7 +701,8 @@ RC_HANDLER(int, ExternalEntityRef, const XML_Char *publicId), int rc=0;, ("(O&NNN)", - conv_string_to_unicode ,context, string_intern(self, base), + conv_string_to_unicode_void, context, + string_intern(self, base), string_intern(self, systemId), string_intern(self, publicId)), rc = PyLong_AsLong(rv);, rc, XML_GetUserData(parser)) @@ -1050,7 +1063,7 @@ pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, if (handler != NULL) { new_parser->handlers[i] = Py_NewRef(handler); struct HandlerInfo info = handler_info[i]; - CALL_XML_HANDLER_SETTER(info, new_parser->itself, info.handler); + CALL_XML_HANDLER_SETTER(&info, new_parser->itself, info.handler); } } @@ -1361,7 +1374,7 @@ xmlparse_handler_setter(PyObject *op, PyObject *v, void *closure) c_handler = handler_info[handlernum].handler; } Py_XSETREF(self->handlers[handlernum], v); - CALL_XML_HANDLER_SETTER(handler_info[handlernum], self->itself, c_handler); + CALL_XML_HANDLER_SETTER(&handler_info[handlernum], self->itself, c_handler); return 0; } @@ -2204,7 +2217,7 @@ clear_handlers(xmlparseobject *self, int initial) } else { Py_CLEAR(self->handlers[i]); - CALL_XML_HANDLER_SETTER(handler_info[i], self->itself, NULL); + CALL_XML_HANDLER_SETTER(&handler_info[i], self->itself, NULL); } } } From 7d9b0e3c992768c7d68052d63d8f9403e1019ee7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 24 Mar 2025 17:57:41 +0100 Subject: [PATCH 2/2] Rage against the paranthesis --- Modules/pyexpat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index bfddc30edfd648..fa153d86543e99 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -116,7 +116,7 @@ static inline void _Py_NO_SANITIZE_UNDEFINED CALL_XML_HANDLER_SETTER(const struct HandlerInfo *handler_info, XML_Parser xml_parser, xmlhandler xml_handler) { - xmlhandlersetter setter = (xmlhandlersetter)(handler_info->setter); + xmlhandlersetter setter = (xmlhandlersetter)handler_info->setter; setter(xml_parser, xml_handler); } @@ -592,7 +592,7 @@ my_ElementDeclHandler(void *userData, if (flush_character_buffer(self) < 0) goto finally; - modelobj = conv_content_model(model, (conv_string_to_unicode_void)); + modelobj = conv_content_model(model, conv_string_to_unicode_void); if (modelobj == NULL) { flag_error(self); goto finally; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy