https://github.com/python/cpython/commit/5fef4ff9ed47e82bce0696672eb2e4bd8953bb1e
commit: 5fef4ff9ed47e82bce0696672eb2e4bd8953bb1e
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]