xmlparse.c: Reject missing call to XML_GetBuffer in XML_ParseBuffer

.. rather than running into undefined behavior.
This commit is contained in:
Sebastian Pipping 2021-02-24 02:12:49 +01:00
parent aafd462fbd
commit 811c41e3be
4 changed files with 32 additions and 1 deletions

View file

@ -3,6 +3,14 @@ NOTE: We are looking for help with a few things:
If you can help, please get in touch. Thanks!
Release x.x.xx xxx xxxxxxx xx xxxx
Bug fixes:
#438 When calling XML_ParseBuffer without a prior successful call to
XML_GetBuffer as a user, no longer trigger undefined behavior
(by adding an integer to a NULL pointer) but rather return
XML_STATUS_ERROR and set the error code to (new) code
XML_ERROR_NO_BUFFER. Found by UBSan (UndefinedBehaviorSanitizer)
of Clang 11 (but not Clang 9).
Other changes:
#422 Windows: Drop support for Visual Studio <=11.0/2012
#382 #428 testrunner: Make verbose mode (argument "-v") report
@ -11,6 +19,8 @@ Release x.x.xx xxx xxxxxxx xx xxxx
Special thanks to:
Oleksandr Popovych
and
Clang 11 UBSan and the Clang team
Release 2.2.10 Sat October 3 2020

View file

@ -115,7 +115,9 @@ enum XML_Error {
XML_ERROR_RESERVED_PREFIX_XMLNS,
XML_ERROR_RESERVED_NAMESPACE_URI,
/* Added in 2.2.1. */
XML_ERROR_INVALID_ARGUMENT
XML_ERROR_INVALID_ARGUMENT,
/* Added in 2.2.11. */
XML_ERROR_NO_BUFFER
};
enum XML_Content_Type {

View file

@ -1883,6 +1883,12 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
parser->m_errorCode = XML_ERROR_FINISHED;
return XML_STATUS_ERROR;
case XML_INITIALIZED:
/* Has someone called XML_GetBuffer successfully before? */
if (! parser->m_bufferPtr) {
parser->m_errorCode = XML_ERROR_NO_BUFFER;
return XML_STATUS_ERROR;
}
if (parser->m_parentParser == NULL && ! startParsing(parser)) {
parser->m_errorCode = XML_ERROR_NO_MEMORY;
return XML_STATUS_ERROR;
@ -2327,6 +2333,10 @@ XML_ErrorString(enum XML_Error code) {
/* Added in 2.2.5. */
case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */
return XML_L("invalid argument");
/* Added in 2.2.11. */
case XML_ERROR_NO_BUFFER:
return XML_L(
"a successful prior call to function XML_GetBuffer is required");
}
return NULL;
}

View file

@ -9833,6 +9833,15 @@ START_TEST(test_nsalloc_parse_buffer) {
/* Try a parse before the start of the world */
/* (Exercises new code path) */
if (XML_ParseBuffer(g_parser, 0, XML_FALSE) != XML_STATUS_ERROR)
fail("Pre-init XML_ParseBuffer not faulted");
if (XML_GetErrorCode(g_parser) != XML_ERROR_NO_BUFFER)
fail("Pre-init XML_ParseBuffer faulted for wrong reason");
buffer = XML_GetBuffer(g_parser, 1 /* any small number greater than 0 */);
if (buffer == NULL)
fail("Could not acquire parse buffer");
allocation_count = 0;
if (XML_ParseBuffer(g_parser, 0, XML_FALSE) != XML_STATUS_ERROR)
fail("Pre-init XML_ParseBuffer not faulted");