Hello, I'm wondering if following xml can *really* creates infinite loop, because it includes %zz entry over and over.
$ LD_PRELOAD=./.libs/libxml2.so ./.libs/xmllint --huge --recover ./crash.xml ----<8----<8----<8----<8----<8----<8----<8----<8----<8 <?m?> <!DOCTYPE[ <!ELEMENT <!ENTITY %xx '<![INCLUDE[%zz;'> <!ENTITY %zz '<![INCLUDE[%zz;'> <!ENTITY z''> %xx; ----<8----<8----<8----<8----<8----<8----<8----<8----<8 xmlParseConditionalSections ... if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) { ... printf("before NEXT '%s'\n", CUR_PTR); NEXT; printf("after NEXT '%s'\n", CUR_PTR); } while (((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') || (NXT(2) != '>'))) && (ctxt->instate != XML_PARSER_EOF)) { if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) { xmlParseConditionalSections(ctxt); ^^^^^^ recursion loop and the output is before NEXT '[%zz;' after NEXT '<![INCLUDE[%zz;' that means, that xmlNextChar() with CUR_PTR containing '[%zz;' expands again to '<![INCLUDE[%zz;', hence it creates infinite recursion loop, which later leads to stack overflow. Does parser parse xml correctly and it's really possible to create infinite recursion? Since my xml-fu is not very good, I have come up with recursion cap, because I have seen it on other places. I wasn't sure, if I can use ctxt->depth, so I did it bit differently. ----<8----<8----<8----<8----<8----<8----<8----<8----<8 diff --git a/parser.c b/parser.c index 53a6b7f0c961..ee2d3c3d4053 100644 --- a/parser.c +++ b/parser.c @@ -6813,9 +6813,17 @@ xmlParseElementDecl(xmlParserCtxtPtr ctxt) { */ static void -xmlParseConditionalSections(xmlParserCtxtPtr ctxt) { +xmlParseConditionalSections(xmlParserCtxtPtr ctxt, int recurse_depth) { int id = ctxt->input->id; + if (((recurse_depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) || + (recurse_depth > 2048)) { + xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR, +"xmlParseConditionalSections : depth %d too deep, use XML_PARSE_HUGE\n", + recurse_depth); + return; + } + SKIP(3); SKIP_BLANKS; if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) { @@ -6848,7 +6856,7 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) { unsigned int cons = ctxt->input->consumed; if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) { - xmlParseConditionalSections(ctxt); + xmlParseConditionalSections(ctxt, recurse_depth + 1); } else if (IS_BLANK_CH(CUR)) { NEXT; } else if (RAW == '%') { @@ -7036,7 +7044,7 @@ xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) { */ if ((ctxt->external == 0) && (ctxt->inputNr > 1)) { if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) { - xmlParseConditionalSections(ctxt); + xmlParseConditionalSections(ctxt, 0); } } @@ -7179,7 +7187,7 @@ xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID, GROW; if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) { - xmlParseConditionalSections(ctxt); + xmlParseConditionalSections(ctxt, 0); } else if (IS_BLANK_CH(CUR)) { NEXT; } else if (RAW == '%') { -- Nikola _______________________________________________ xml mailing list, project page http://xmlsoft.org/ xml@gnome.org https://mail.gnome.org/mailman/listinfo/xml