Skip to content

Commit 5fef4ff

Browse files
authored
gh-111178: Fix function signature in pyexpat.c (#131674)
Move _Py_NO_SANITIZE_UNDEFINED macro from faulthandler.c to pyport.h.
1 parent d16f455 commit 5fef4ff

File tree

3 files changed

+49
-33
lines changed

3 files changed

+49
-33
lines changed

Include/pyport.h

+20
Original file line numberDiff line numberDiff line change
@@ -655,4 +655,24 @@ extern "C" {
655655
# define _Py_FALLTHROUGH do { } while (0)
656656
#endif
657657

658+
659+
// _Py_NO_SANITIZE_UNDEFINED(): Disable Undefined Behavior sanitizer (UBsan)
660+
// on a function.
661+
//
662+
// Clang and GCC 9.0+ use __attribute__((no_sanitize("undefined"))).
663+
// GCC 4.9+ uses __attribute__((no_sanitize_undefined)).
664+
#if defined(__has_feature)
665+
# if __has_feature(undefined_behavior_sanitizer)
666+
# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined")))
667+
# endif
668+
#endif
669+
#if !defined(_Py_NO_SANITIZE_UNDEFINED) && defined(__GNUC__) \
670+
&& ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9))
671+
# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined))
672+
#endif
673+
#ifndef _Py_NO_SANITIZE_UNDEFINED
674+
# define _Py_NO_SANITIZE_UNDEFINED
675+
#endif
676+
677+
658678
#endif /* Py_PYPORT_H */

Modules/faulthandler.c

-17
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,6 @@
4040
#define PUTS(fd, str) (void)_Py_write_noraise(fd, str, strlen(str))
4141

4242

43-
// Clang and GCC 9.0+ use __attribute__((no_sanitize("undefined")))
44-
#if defined(__has_feature)
45-
# if __has_feature(undefined_behavior_sanitizer)
46-
# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined")))
47-
# endif
48-
#endif
49-
50-
// GCC 4.9+ uses __attribute__((no_sanitize_undefined))
51-
#if !defined(_Py_NO_SANITIZE_UNDEFINED) && defined(__GNUC__) \
52-
&& ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9))
53-
# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined))
54-
#endif
55-
#ifndef _Py_NO_SANITIZE_UNDEFINED
56-
# define _Py_NO_SANITIZE_UNDEFINED
57-
#endif
58-
59-
6043
typedef struct {
6144
int signum;
6245
int enabled;

Modules/pyexpat.c

+29-16
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,15 @@ struct HandlerInfo {
110110

111111
static struct HandlerInfo handler_info[64];
112112

113-
#define CALL_XML_HANDLER_SETTER(HANDLER_INFO, XML_PARSER, XML_HANDLER) \
114-
do { \
115-
xmlhandlersetter setter = (xmlhandlersetter)(HANDLER_INFO).setter; \
116-
setter((XML_PARSER), (XML_HANDLER)); \
117-
} while (0)
113+
// gh-111178: Use _Py_NO_SANITIZE_UNDEFINED, rather than using the exact
114+
// handler API for each handler.
115+
static inline void _Py_NO_SANITIZE_UNDEFINED
116+
CALL_XML_HANDLER_SETTER(const struct HandlerInfo *handler_info,
117+
XML_Parser xml_parser, xmlhandler xml_handler)
118+
{
119+
xmlhandlersetter setter = (xmlhandlersetter)handler_info->setter;
120+
setter(xml_parser, xml_handler);
121+
}
118122

119123
/* Set an integer attribute on the error object; return true on success,
120124
* false on an exception.
@@ -182,6 +186,12 @@ conv_string_to_unicode(const XML_Char *str)
182186
return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
183187
}
184188

189+
static PyObject *
190+
conv_string_to_unicode_void(void *arg)
191+
{
192+
return conv_string_to_unicode((const XML_Char *)arg);
193+
}
194+
185195
static PyObject *
186196
conv_string_len_to_unicode(const XML_Char *str, int len)
187197
{
@@ -498,7 +508,7 @@ VOID_HANDLER(ProcessingInstruction,
498508
(void *userData,
499509
const XML_Char *target,
500510
const XML_Char *data),
501-
("(NO&)", string_intern(self, target), conv_string_to_unicode ,data))
511+
("(NO&)", string_intern(self, target), conv_string_to_unicode_void, data))
502512

503513
VOID_HANDLER(UnparsedEntityDecl,
504514
(void *userData,
@@ -535,12 +545,13 @@ VOID_HANDLER(XmlDecl,
535545
const XML_Char *encoding,
536546
int standalone),
537547
("(O&O&i)",
538-
conv_string_to_unicode ,version, conv_string_to_unicode ,encoding,
548+
conv_string_to_unicode_void, version,
549+
conv_string_to_unicode_void, encoding,
539550
standalone))
540551

541552
static PyObject *
542553
conv_content_model(XML_Content * const model,
543-
PyObject *(*conv_string)(const XML_Char *))
554+
PyObject *(*conv_string)(void *))
544555
{
545556
PyObject *result = NULL;
546557
PyObject *children = PyTuple_New(model->numchildren);
@@ -559,7 +570,7 @@ conv_content_model(XML_Content * const model,
559570
}
560571
result = Py_BuildValue("(iiO&N)",
561572
model->type, model->quant,
562-
conv_string,model->name, children);
573+
conv_string, model->name, children);
563574
}
564575
return result;
565576
}
@@ -581,7 +592,7 @@ my_ElementDeclHandler(void *userData,
581592

582593
if (flush_character_buffer(self) < 0)
583594
goto finally;
584-
modelobj = conv_content_model(model, (conv_string_to_unicode));
595+
modelobj = conv_content_model(model, conv_string_to_unicode_void);
585596
if (modelobj == NULL) {
586597
flag_error(self);
587598
goto finally;
@@ -622,7 +633,8 @@ VOID_HANDLER(AttlistDecl,
622633
int isrequired),
623634
("(NNO&O&i)",
624635
string_intern(self, elname), string_intern(self, attname),
625-
conv_string_to_unicode ,att_type, conv_string_to_unicode ,dflt,
636+
conv_string_to_unicode_void, att_type,
637+
conv_string_to_unicode_void, dflt,
626638
isrequired))
627639

628640
#if XML_COMBINED_VERSION >= 19504
@@ -658,7 +670,7 @@ VOID_HANDLER(EndNamespaceDecl,
658670

659671
VOID_HANDLER(Comment,
660672
(void *userData, const XML_Char *data),
661-
("(O&)", conv_string_to_unicode ,data))
673+
("(O&)", conv_string_to_unicode_void, data))
662674

663675
VOID_HANDLER(StartCdataSection,
664676
(void *userData),
@@ -689,7 +701,8 @@ RC_HANDLER(int, ExternalEntityRef,
689701
const XML_Char *publicId),
690702
int rc=0;,
691703
("(O&NNN)",
692-
conv_string_to_unicode ,context, string_intern(self, base),
704+
conv_string_to_unicode_void, context,
705+
string_intern(self, base),
693706
string_intern(self, systemId), string_intern(self, publicId)),
694707
rc = PyLong_AsLong(rv);, rc,
695708
XML_GetUserData(parser))
@@ -1050,7 +1063,7 @@ pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self,
10501063
if (handler != NULL) {
10511064
new_parser->handlers[i] = Py_NewRef(handler);
10521065
struct HandlerInfo info = handler_info[i];
1053-
CALL_XML_HANDLER_SETTER(info, new_parser->itself, info.handler);
1066+
CALL_XML_HANDLER_SETTER(&info, new_parser->itself, info.handler);
10541067
}
10551068
}
10561069

@@ -1361,7 +1374,7 @@ xmlparse_handler_setter(PyObject *op, PyObject *v, void *closure)
13611374
c_handler = handler_info[handlernum].handler;
13621375
}
13631376
Py_XSETREF(self->handlers[handlernum], v);
1364-
CALL_XML_HANDLER_SETTER(handler_info[handlernum], self->itself, c_handler);
1377+
CALL_XML_HANDLER_SETTER(&handler_info[handlernum], self->itself, c_handler);
13651378
return 0;
13661379
}
13671380

@@ -2204,7 +2217,7 @@ clear_handlers(xmlparseobject *self, int initial)
22042217
}
22052218
else {
22062219
Py_CLEAR(self->handlers[i]);
2207-
CALL_XML_HANDLER_SETTER(handler_info[i], self->itself, NULL);
2220+
CALL_XML_HANDLER_SETTER(&handler_info[i], self->itself, NULL);
22082221
}
22092222
}
22102223
}

0 commit comments

Comments
 (0)