diff --git a/include/libxml/xpathInternals.h b/include/libxml/xpathInternals.h index cb0991d7..57ff7a8d 100644 --- a/include/libxml/xpathInternals.h +++ b/include/libxml/xpathInternals.h @@ -273,7 +273,8 @@ XMLPUBFUN void * * type. */ #define CHECK_TYPE(typeval) \ - if ((ctxt->value == NULL) || (ctxt->value->type != typeval)) \ + if ((ctxt->error != 0) || \ + (ctxt->value == NULL) || (ctxt->value->type != typeval)) \ XP_ERROR(XPATH_INVALID_TYPE) /** diff --git a/xpath.c b/xpath.c index a500a206..f14ab475 100644 --- a/xpath.c +++ b/xpath.c @@ -2873,7 +2873,15 @@ valuePop(xmlXPathParserContextPtr ctxt) { xmlXPathObjectPtr ret; - if ((ctxt == NULL) || (ctxt->valueNr <= 0)) + /* + * If a memory allocation failed, it can happen that valuePush doesn't + * push a value on the stack. If there's no error check before the + * corresponding valuePop call, we would pop an unrelated object which + * could lead to use-after-free errors later on. So we don't pop values + * if an error was signaled. The stack will be cleaned later in + * xmlXPathFreeParserContext. + */ + if ((ctxt == NULL) || (ctxt->valueNr <= 0) || (ctxt->error != 0)) return (NULL); if (ctxt->valueNr <= ctxt->valueFrame) {