@@ -110,11 +110,15 @@ struct HandlerInfo {
110110
111111static 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+
185195static PyObject *
186196conv_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
503513VOID_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
541552static PyObject *
542553conv_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
659671VOID_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
663675VOID_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