https://github.com/python/cpython/commit/5fef4ff9ed47e82bce0696672eb2e4bd8953bb1e
commit: 5fef4ff9ed47e82bce0696672eb2e4bd8953bb1e
branch: main
author: Victor Stinner <vstin...@python.org>
committer: vstinner <vstin...@python.org>
date: 2025-03-24T17:22:45Z
summary:

gh-111178: Fix function signature in pyexpat.c (#131674)

Move _Py_NO_SANITIZE_UNDEFINED macro from faulthandler.c to pyport.h.

files:
M Include/pyport.h
M Modules/faulthandler.c
M Modules/pyexpat.c

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..fa153d86543e99 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);
         }
     }
 }

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to