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:
parent
d16f455cd8
commit
5fef4ff9ed
@ -655,4 +655,24 @@ extern "C" {
|
|||||||
# define _Py_FALLTHROUGH do { } while (0)
|
# define _Py_FALLTHROUGH do { } while (0)
|
||||||
#endif
|
#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 */
|
#endif /* Py_PYPORT_H */
|
||||||
|
@ -40,23 +40,6 @@
|
|||||||
#define PUTS(fd, str) (void)_Py_write_noraise(fd, str, strlen(str))
|
#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 {
|
typedef struct {
|
||||||
int signum;
|
int signum;
|
||||||
int enabled;
|
int enabled;
|
||||||
|
@ -110,11 +110,15 @@ struct HandlerInfo {
|
|||||||
|
|
||||||
static struct HandlerInfo handler_info[64];
|
static struct HandlerInfo handler_info[64];
|
||||||
|
|
||||||
#define CALL_XML_HANDLER_SETTER(HANDLER_INFO, XML_PARSER, XML_HANDLER) \
|
// gh-111178: Use _Py_NO_SANITIZE_UNDEFINED, rather than using the exact
|
||||||
do { \
|
// handler API for each handler.
|
||||||
xmlhandlersetter setter = (xmlhandlersetter)(HANDLER_INFO).setter; \
|
static inline void _Py_NO_SANITIZE_UNDEFINED
|
||||||
setter((XML_PARSER), (XML_HANDLER)); \
|
CALL_XML_HANDLER_SETTER(const struct HandlerInfo *handler_info,
|
||||||
} while (0)
|
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,
|
/* Set an integer attribute on the error object; return true on success,
|
||||||
* false on an exception.
|
* false on an exception.
|
||||||
@ -182,6 +186,12 @@ conv_string_to_unicode(const XML_Char *str)
|
|||||||
return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
|
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 *
|
static PyObject *
|
||||||
conv_string_len_to_unicode(const XML_Char *str, int len)
|
conv_string_len_to_unicode(const XML_Char *str, int len)
|
||||||
{
|
{
|
||||||
@ -498,7 +508,7 @@ VOID_HANDLER(ProcessingInstruction,
|
|||||||
(void *userData,
|
(void *userData,
|
||||||
const XML_Char *target,
|
const XML_Char *target,
|
||||||
const XML_Char *data),
|
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_HANDLER(UnparsedEntityDecl,
|
||||||
(void *userData,
|
(void *userData,
|
||||||
@ -535,12 +545,13 @@ VOID_HANDLER(XmlDecl,
|
|||||||
const XML_Char *encoding,
|
const XML_Char *encoding,
|
||||||
int standalone),
|
int standalone),
|
||||||
("(O&O&i)",
|
("(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))
|
standalone))
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
conv_content_model(XML_Content * const model,
|
conv_content_model(XML_Content * const model,
|
||||||
PyObject *(*conv_string)(const XML_Char *))
|
PyObject *(*conv_string)(void *))
|
||||||
{
|
{
|
||||||
PyObject *result = NULL;
|
PyObject *result = NULL;
|
||||||
PyObject *children = PyTuple_New(model->numchildren);
|
PyObject *children = PyTuple_New(model->numchildren);
|
||||||
@ -559,7 +570,7 @@ conv_content_model(XML_Content * const model,
|
|||||||
}
|
}
|
||||||
result = Py_BuildValue("(iiO&N)",
|
result = Py_BuildValue("(iiO&N)",
|
||||||
model->type, model->quant,
|
model->type, model->quant,
|
||||||
conv_string,model->name, children);
|
conv_string, model->name, children);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -581,7 +592,7 @@ my_ElementDeclHandler(void *userData,
|
|||||||
|
|
||||||
if (flush_character_buffer(self) < 0)
|
if (flush_character_buffer(self) < 0)
|
||||||
goto finally;
|
goto finally;
|
||||||
modelobj = conv_content_model(model, (conv_string_to_unicode));
|
modelobj = conv_content_model(model, conv_string_to_unicode_void);
|
||||||
if (modelobj == NULL) {
|
if (modelobj == NULL) {
|
||||||
flag_error(self);
|
flag_error(self);
|
||||||
goto finally;
|
goto finally;
|
||||||
@ -622,7 +633,8 @@ VOID_HANDLER(AttlistDecl,
|
|||||||
int isrequired),
|
int isrequired),
|
||||||
("(NNO&O&i)",
|
("(NNO&O&i)",
|
||||||
string_intern(self, elname), string_intern(self, attname),
|
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))
|
isrequired))
|
||||||
|
|
||||||
#if XML_COMBINED_VERSION >= 19504
|
#if XML_COMBINED_VERSION >= 19504
|
||||||
@ -658,7 +670,7 @@ VOID_HANDLER(EndNamespaceDecl,
|
|||||||
|
|
||||||
VOID_HANDLER(Comment,
|
VOID_HANDLER(Comment,
|
||||||
(void *userData, const XML_Char *data),
|
(void *userData, const XML_Char *data),
|
||||||
("(O&)", conv_string_to_unicode ,data))
|
("(O&)", conv_string_to_unicode_void, data))
|
||||||
|
|
||||||
VOID_HANDLER(StartCdataSection,
|
VOID_HANDLER(StartCdataSection,
|
||||||
(void *userData),
|
(void *userData),
|
||||||
@ -689,7 +701,8 @@ RC_HANDLER(int, ExternalEntityRef,
|
|||||||
const XML_Char *publicId),
|
const XML_Char *publicId),
|
||||||
int rc=0;,
|
int rc=0;,
|
||||||
("(O&NNN)",
|
("(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)),
|
string_intern(self, systemId), string_intern(self, publicId)),
|
||||||
rc = PyLong_AsLong(rv);, rc,
|
rc = PyLong_AsLong(rv);, rc,
|
||||||
XML_GetUserData(parser))
|
XML_GetUserData(parser))
|
||||||
@ -1050,7 +1063,7 @@ pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self,
|
|||||||
if (handler != NULL) {
|
if (handler != NULL) {
|
||||||
new_parser->handlers[i] = Py_NewRef(handler);
|
new_parser->handlers[i] = Py_NewRef(handler);
|
||||||
struct HandlerInfo info = handler_info[i];
|
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;
|
c_handler = handler_info[handlernum].handler;
|
||||||
}
|
}
|
||||||
Py_XSETREF(self->handlers[handlernum], v);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2204,7 +2217,7 @@ clear_handlers(xmlparseobject *self, int initial)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Py_CLEAR(self->handlers[i]);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user