Try to parse even when incoming len is zero

If the reparse deferral setting has changed, it may be possible to
finish a token.
This commit is contained in:
Snild Dolkow 2023-09-29 10:14:59 +02:00
parent 1d3162da8a
commit 8ddd8e86aa
2 changed files with 10 additions and 50 deletions

View file

@ -1914,46 +1914,8 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) {
parser->m_parsingStatus.parsing = XML_PARSING;
}
if (len == 0) {
parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
if (! isFinal)
return XML_STATUS_OK;
parser->m_positionPtr = parser->m_bufferPtr;
parser->m_parseEndPtr = parser->m_bufferEnd;
/* If data are left over from last buffer, and we now know that these
data are the final chunk of input, then we have to check them again
to detect errors based on that fact.
*/
parser->m_errorCode
= callProcessor(parser, parser->m_bufferPtr, parser->m_parseEndPtr,
&parser->m_bufferPtr);
if (parser->m_errorCode == XML_ERROR_NONE) {
switch (parser->m_parsingStatus.parsing) {
case XML_SUSPENDED:
/* While we added no new data, the finalBuffer flag may have caused
* us to parse previously-unparsed data in the internal buffer.
* If that triggered a callback to the application, it would have
* had an opportunity to suspend parsing. */
XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
parser->m_bufferPtr, &parser->m_position);
parser->m_positionPtr = parser->m_bufferPtr;
return XML_STATUS_SUSPENDED;
case XML_INITIALIZED:
case XML_PARSING:
parser->m_parsingStatus.parsing = XML_FINISHED;
/* fall through */
default:
return XML_STATUS_OK;
}
}
parser->m_eventEndPtr = parser->m_eventPtr;
parser->m_processor = errorProcessor;
return XML_STATUS_ERROR;
}
#if XML_CONTEXT_BYTES == 0
else if (parser->m_bufferPtr == parser->m_bufferEnd) {
if (parser->m_bufferPtr == parser->m_bufferEnd) {
const char *end;
int nLeftOver;
enum XML_Status result;
@ -2023,15 +1985,14 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) {
return result;
}
#endif /* XML_CONTEXT_BYTES == 0 */
else {
void *buff = XML_GetBuffer(parser, len);
if (buff == NULL)
return XML_STATUS_ERROR;
else {
memcpy(buff, s, len);
return XML_ParseBuffer(parser, len, isFinal);
}
void *buff = XML_GetBuffer(parser, len);
if (buff == NULL)
return XML_STATUS_ERROR;
if (len > 0) {
assert(s != NULL); // make sure s==NULL && len!=0 was rejected above
memcpy(buff, s, len);
}
return XML_ParseBuffer(parser, len, isFinal);
}
enum XML_Status XMLCALL

View file

@ -5387,8 +5387,7 @@ END_TEST
START_TEST(test_set_reparse_deferral_on_the_fly) {
const char *const pre = "<d><x attr='";
const char *const end = "'></x";
const char *const post = ">";
const char *const end = "'></x>";
char iiiiii[100];
const int fillsize = (int)sizeof(iiiiii);
memset(iiiiii, 'i', fillsize);
@ -5427,7 +5426,7 @@ START_TEST(test_set_reparse_deferral_on_the_fly) {
// now change the heuristic setting and add *no* data
assert_true(XML_SetReparseDeferralEnabled(parser, XML_FALSE));
// we avoid isFinal=XML_TRUE, because that would force-bypass the heuristic.
status = XML_Parse(parser, post, (int)strlen(post), XML_FALSE);
status = XML_Parse(parser, "", 0, XML_FALSE);
if (status != XML_STATUS_OK) {
xml_failure(parser);
}