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

Move _Py_NO_SANITIZE_UNDEFINED macro from faulthandler.c to pyport.h.
This commit is contained in:
Victor Stinner 2025-03-24 18:22:45 +01:00 committed by GitHub
parent d16f455cd8
commit 5fef4ff9ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 33 deletions

View File

@ -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 */

View File

@ -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;

View File

@ -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);
@ -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);
}
}
}