1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-29 11:41:22 +03:00

Fixed memory leak reported by Dave Beckett Removed spurious comment

* parser.c, xmlmemory.c, include/libxml/xmlmemory.h: Fixed
  memory leak reported by Dave Beckett
* xmlschemas.c: Removed spurious comment reported on the mailing
  list
* xinclude.c, xpath.c, xpointer.c, libxml/include/xpointer.h:
  Further work on Bug 129967 concerning xpointer range handling
  and range-to function; much better, but still not complete
This commit is contained in:
William M. Brack
2003-12-30 08:30:19 +00:00
parent 1f5c9891a0
commit 72ee48d55f
9 changed files with 103 additions and 52 deletions

View File

@ -1,3 +1,13 @@
Tue Dec 30 16:26:13 HKT 2003 William Brack <wbrack@mmm.com.hk>
* parser.c, xmlmemory.c, include/libxml/xmlmemory.h: Fixed
memory leak reported by Dave Beckett
* xmlschemas.c: Removed spurious comment reported on the mailing
list
* xinclude.c, xpath.c, xpointer.c, libxml/include/xpointer.h:
Further work on Bug 129967 concerning xpointer range handling
and range-to function; much better, but still not complete
Mon Dec 29 18:08:05 CET 2003 Daniel Veillard <daniel@veillard.com> Mon Dec 29 18:08:05 CET 2003 Daniel Veillard <daniel@veillard.com>
* valid.c: xmlValidateElement could crash for element holding a * valid.c: xmlValidateElement could crash for element holding a

View File

@ -129,6 +129,11 @@ XMLPUBFUN int XMLCALL
XMLPUBFUN int XMLCALL XMLPUBFUN int XMLCALL
xmlInitMemory (void); xmlInitMemory (void);
/*
* Cleanup of the memory layer.
*/
XMLPUBFUN void XMLCALL
xmlCleanupMemory (void);
/* /*
* These are specific to the XML debug memory wrapper. * These are specific to the XML debug memory wrapper.
*/ */

View File

@ -103,7 +103,8 @@ XMLPUBFUN xmlNodePtr XMLCALL
xmlXPtrBuildNodeList (xmlXPathObjectPtr obj); xmlXPtrBuildNodeList (xmlXPathObjectPtr obj);
XMLPUBFUN void XMLCALL XMLPUBFUN void XMLCALL
xmlXPtrEvalRangePredicate (xmlXPathParserContextPtr ctxt); xmlXPtrEvalRangePredicate (xmlXPathParserContextPtr ctxt);
XMLPUBFUN xmlNodePtr XMLCALL
xmlXPtrAdvanceNode (xmlNodePtr cur);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -12112,6 +12112,7 @@ xmlCleanupParser(void) {
xmlCleanupGlobals(); xmlCleanupGlobals();
xmlResetLastError(); xmlResetLastError();
xmlCleanupThreads(); /* must be last if called not from the main thread */ xmlCleanupThreads(); /* must be last if called not from the main thread */
xmlCleanupMemory();
xmlParserInitialized = 0; xmlParserInitialized = 0;
} }

View File

@ -38,7 +38,7 @@
/************************************************************************ /************************************************************************
* * * *
* XInclude contexts handling * * XInclude context handling *
* * * *
************************************************************************/ ************************************************************************/
@ -50,7 +50,7 @@ typedef xmlChar *xmlURL;
typedef struct _xmlXIncludeRef xmlXIncludeRef; typedef struct _xmlXIncludeRef xmlXIncludeRef;
typedef xmlXIncludeRef *xmlXIncludeRefPtr; typedef xmlXIncludeRef *xmlXIncludeRefPtr;
struct _xmlXIncludeRef { struct _xmlXIncludeRef {
xmlChar *URI; /* the rully resolved resource URL */ xmlChar *URI; /* the fully resolved resource URL */
xmlChar *fragment; /* the fragment in the URI */ xmlChar *fragment; /* the fragment in the URI */
xmlDocPtr doc; /* the parsed document */ xmlDocPtr doc; /* the parsed document */
xmlNodePtr ref; /* the node making the reference in the source */ xmlNodePtr ref; /* the node making the reference in the source */
@ -70,12 +70,12 @@ struct _xmlXIncludeCtxt {
int txtNr; /* number of unparsed documents */ int txtNr; /* number of unparsed documents */
int txtMax; /* size of unparsed documents tab */ int txtMax; /* size of unparsed documents tab */
xmlNodePtr *txtTab; /* array of unparsed text nodes */ xmlNodePtr *txtTab; /* array of unparsed text nodes */
xmlURL *txturlTab; /* array of unparsed txtuments URLs */ xmlURL *txturlTab; /* array of unparsed text URLs */
xmlChar * url; /* the current URL processed */ xmlChar * url; /* the current URL processed */
int urlNr; /* number of url stacked */ int urlNr; /* number of URLs stacked */
int urlMax; /* size of url stack */ int urlMax; /* size of URL stack */
xmlChar * *urlTab; /* url stack */ xmlChar * *urlTab; /* URL stack */
int nbErrors; /* the number of errors detected */ int nbErrors; /* the number of errors detected */
int legacy; /* using XINCLUDE_OLD_NS */ int legacy; /* using XINCLUDE_OLD_NS */
@ -94,7 +94,7 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree);
/** /**
* xmlXIncludeErrMemory: * xmlXIncludeErrMemory:
* @extra: extra informations * @extra: extra information
* *
* Handle an out of memory condition * Handle an out of memory condition
*/ */
@ -115,7 +115,7 @@ xmlXIncludeErrMemory(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node,
* @ctxt: the XInclude context * @ctxt: the XInclude context
* @node: the context node * @node: the context node
* @msg: the error message * @msg: the error message
* @extra: extra informations * @extra: extra information
* *
* Handle an XInclude error * Handle an XInclude error
*/ */
@ -136,7 +136,7 @@ xmlXIncludeErr(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,
* @ctxt: the XInclude context * @ctxt: the XInclude context
* @node: the context node * @node: the context node
* @msg: the error message * @msg: the error message
* @extra: extra informations * @extra: extra information
* *
* Emit an XInclude warning. * Emit an XInclude warning.
*/ */
@ -341,7 +341,7 @@ xmlXIncludeURLPush(xmlXIncludeCtxtPtr ctxt,
* xmlXIncludeURLPop: * xmlXIncludeURLPop:
* @ctxt: the parser context * @ctxt: the parser context
* *
* Pops the top url from the url stack * Pops the top URL from the URL stack
*/ */
static void static void
xmlXIncludeURLPop(xmlXIncludeCtxtPtr ctxt) xmlXIncludeURLPop(xmlXIncludeCtxtPtr ctxt)
@ -402,7 +402,7 @@ xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {
* @ctxt: the XInclude context * @ctxt: the XInclude context
* @URL: the URL or file path * @URL: the URL or file path
* *
* parse an document for XInclude * parse a document for XInclude
*/ */
static xmlDocPtr static xmlDocPtr
xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) { xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
@ -419,7 +419,7 @@ xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
return(NULL); return(NULL);
} }
/* /*
* try to ensure that the new document included are actually * try to ensure that new documents included are actually
* built with the same dictionary as the including document. * built with the same dictionary as the including document.
*/ */
if ((ctxt->doc != NULL) && (ctxt->doc->dict != NULL) && if ((ctxt->doc != NULL) && (ctxt->doc->dict != NULL) &&
@ -675,7 +675,7 @@ xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
newctxt->urlTab = ctxt->urlTab; newctxt->urlTab = ctxt->urlTab;
/* /*
* Inherit the documents already in use by others includes * Inherit the documents already in use by other includes
*/ */
newctxt->incBase = ctxt->incNr; newctxt->incBase = ctxt->incNr;
for (i = 0;i < ctxt->incNr;i++) { for (i = 0;i < ctxt->incNr;i++) {
@ -818,11 +818,11 @@ xmlXIncludeCopyNodeList(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
} }
/** /**
* xmlXInclueGetNthChild: * xmlXIncludeGetNthChild:
* @cur: the node * @cur: the node
* @no: the child number * @no: the child number
* *
* Returns the @no'th element child of @cur or NULL * Returns the @n'th element child of @cur or NULL
*/ */
static xmlNodePtr static xmlNodePtr
xmlXIncludeGetNthChild(xmlNodePtr cur, int no) { xmlXIncludeGetNthChild(xmlNodePtr cur, int no) {
@ -844,8 +844,6 @@ xmlXIncludeGetNthChild(xmlNodePtr cur, int no) {
return(cur); return(cur);
} }
xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur);
/** /**
* xmlXIncludeCopyRange: * xmlXIncludeCopyRange:
* @ctxt: the XInclude context * @ctxt: the XInclude context
@ -856,7 +854,7 @@ xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur);
* Build a node list tree copy of the XPointer result. * Build a node list tree copy of the XPointer result.
* *
* Returns an xmlNodePtr list or NULL. * Returns an xmlNodePtr list or NULL.
* the caller has to free the node tree. * The caller has to free the node tree.
*/ */
static xmlNodePtr static xmlNodePtr
xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target, xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
@ -884,7 +882,7 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
index1 = range->index; index1 = range->index;
index2 = range->index2; index2 = range->index2;
while (cur != NULL) { while (cur != NULL) {
if (cur == end) { if (cur == end) { /* Are we at the end of the range? */
if (cur->type == XML_TEXT_NODE) { if (cur->type == XML_TEXT_NODE) {
const xmlChar *content = cur->content; const xmlChar *content = cur->content;
int len; int len;
@ -911,7 +909,7 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
else else
xmlAddChild(parent, tmp); xmlAddChild(parent, tmp);
return(list); return(list);
} else { } else { /* ending node not a text node */
tmp = xmlDocCopyNode(cur, target, 0); tmp = xmlDocCopyNode(cur, target, 0);
if (list == NULL) if (list == NULL)
list = tmp; list = tmp;
@ -939,7 +937,7 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
*/ */
continue; /* while */ continue; /* while */
} }
} else if ((cur == start) && } else if ((cur == start) && /* Not at the end, are we at start? */
(list == NULL) /* looks superfluous but ... */ ) { (list == NULL) /* looks superfluous but ... */ ) {
if ((cur->type == XML_TEXT_NODE) || if ((cur->type == XML_TEXT_NODE) ||
(cur->type == XML_CDATA_SECTION_NODE)) { (cur->type == XML_CDATA_SECTION_NODE)) {
@ -950,12 +948,13 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
} else { } else {
if (index1 > 1) { if (index1 > 1) {
content += (index1 - 1); content += (index1 - 1);
index1 = 0;
} }
tmp = xmlNewText(content); tmp = xmlNewText(content);
} }
last = list = tmp; last = list = tmp;
} else { } else { /* Not text node */
if ((cur == start) && (index1 > 1)) { if (index1 > 1) { /* Do we need to position? */
tmp = xmlDocCopyNode(cur, target, 0); tmp = xmlDocCopyNode(cur, target, 0);
list = tmp; list = tmp;
parent = tmp; parent = tmp;
@ -967,7 +966,7 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
*/ */
continue; /* while */ continue; /* while */
} }
tmp = xmlDocCopyNode(cur, target, 1); tmp = xmlDocCopyNode(cur, target, 0);
list = tmp; list = tmp;
parent = NULL; parent = NULL;
last = tmp; last = tmp;
@ -992,7 +991,7 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
/* Humm, should not happen ! */ /* Humm, should not happen ! */
break; break;
default: default:
tmp = xmlDocCopyNode(cur, target, 1); tmp = xmlDocCopyNode(cur, target, 0);
break; break;
} }
if (tmp != NULL) { if (tmp != NULL) {

View File

@ -811,6 +811,20 @@ xmlInitMemory(void)
return(0); return(0);
} }
/**
* xmlCleanupMemory:
*
* Free up all the memory associated with memorys
*/
void
xmlCleanupMemory(void) {
if (xmlMemInitialized == 0)
return;
xmlFreeMutex(xmlMemMutex);
xmlMemInitialized = 0;
}
/** /**
* xmlMemSetup: * xmlMemSetup:
* @freeFunc: the free() function to use * @freeFunc: the free() function to use

View File

@ -901,15 +901,6 @@ xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
* Utilities * * Utilities *
* * * *
************************************************************************/ ************************************************************************/
/**
* numberedString:
* @prefix: the string prefix
* @number: the number
*
* Build a new numbered string
*
* Returns the new string
*/
/** /**
* xmlSchemaGetProp: * xmlSchemaGetProp:

48
xpath.c
View File

@ -10307,11 +10307,12 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
ctxt->context->doc = bakd; ctxt->context->doc = bakd;
ctxt->context->node = bak; ctxt->context->node = bak;
CHECK_ERROR0; CHECK_ERROR0;
if (op->ch2 != -1) if (op->ch2 != -1) {
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
ctxt->context->doc = bakd; ctxt->context->doc = bakd;
ctxt->context->node = bak; ctxt->context->node = bak;
CHECK_ERROR0; CHECK_ERROR0;
}
return (total); return (total);
case XPATH_OP_PREDICATE: case XPATH_OP_PREDICATE:
case XPATH_OP_FILTER:{ case XPATH_OP_FILTER:{
@ -10594,7 +10595,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
xmlLocationSetPtr newlocset = NULL; xmlLocationSetPtr newlocset = NULL;
xmlLocationSetPtr oldlocset; xmlLocationSetPtr oldlocset;
xmlNodeSetPtr oldset; xmlNodeSetPtr oldset;
int i; int i, j;
if (op->ch1 != -1) if (op->ch1 != -1)
total += total +=
@ -10611,9 +10612,9 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
CHECK_TYPE0(XPATH_LOCATIONSET); CHECK_TYPE0(XPATH_LOCATIONSET);
obj = valuePop(ctxt); obj = valuePop(ctxt);
oldlocset = obj->user; oldlocset = obj->user;
ctxt->context->node = NULL;
if ((oldlocset == NULL) || (oldlocset->locNr == 0)) { if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
ctxt->context->node = NULL;
ctxt->context->contextSize = 0; ctxt->context->contextSize = 0;
ctxt->context->proximityPosition = 0; ctxt->context->proximityPosition = 0;
total += xmlXPathCompOpEval(ctxt,&comp->steps[op->ch2]); total += xmlXPathCompOpEval(ctxt,&comp->steps[op->ch2]);
@ -10631,11 +10632,11 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
* Run the evaluation with a node list made of a * Run the evaluation with a node list made of a
* single item in the nodelocset. * single item in the nodelocset.
*/ */
ctxt->context->node = oldlocset->locTab[i]->user; ctxt->context->node = (xmlNodePtr)ctxt->context->doc;
ctxt->context->contextSize = 1;
ctxt->context->proximityPosition = 1;
tmp = xmlXPathNewNodeSet(ctxt->context->node); tmp = xmlXPathNewNodeSet(ctxt->context->node);
valuePush(ctxt, tmp); valuePush(ctxt, tmp);
ctxt->context->contextSize = oldlocset->locNr;
ctxt->context->proximityPosition = i + 1;
if (op->ch2 != -1) if (op->ch2 != -1)
total += total +=
@ -10644,14 +10645,29 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
CHECK_ERROR0; CHECK_ERROR0;
/* /*
* The result of the evaluation need to be tested to * The result of the evaluation needs to be tested to
* decided whether the filter succeeded or not * decide whether the filter succeeded or not
*/ */
res = valuePop(ctxt); res = valuePop(ctxt);
if (xmlXPathEvaluatePredicateResult(ctxt, res)) { if (res->type == XPATH_LOCATIONSET) {
xmlXPtrLocationSetAdd(newlocset, xmlLocationSetPtr rloc =
xmlXPathObjectCopy (xmlLocationSetPtr)res->user;
(oldlocset->locTab[i])); for (j=0; j<rloc->locNr; j++) {
range = xmlXPtrNewRange(
oldlocset->locTab[i]->user,
oldlocset->locTab[i]->index,
rloc->locTab[j]->user2,
rloc->locTab[j]->index2);
if (range != NULL) {
xmlXPtrLocationSetAdd(newlocset, range);
}
}
} else {
range = xmlXPtrNewRangeNodeObject(
(xmlNodePtr)oldlocset->locTab[i]->user, res);
if (range != NULL) {
xmlXPtrLocationSetAdd(newlocset,range);
}
} }
/* /*
@ -10666,7 +10682,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
ctxt->context->node = NULL; ctxt->context->node = NULL;
} }
} else { /* Not a location set */ } else { /* Not a location set */
CHECK_TYPE0(XPATH_NODESET); CHECK_TYPE0(XPATH_NODESET);
obj = valuePop(ctxt); obj = valuePop(ctxt);
oldset = obj->nodesetval; oldset = obj->nodesetval;

View File

@ -124,7 +124,6 @@ xmlXPtrErr(xmlXPathParserContextPtr ctxt, int error,
* * * *
************************************************************************/ ************************************************************************/
xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur);
/** /**
* xmlXPtrGetArity: * xmlXPtrGetArity:
* @cur: the node * @cur: the node
@ -549,6 +548,7 @@ xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
return(NULL); return(NULL);
switch (end->type) { switch (end->type) {
case XPATH_POINT: case XPATH_POINT:
case XPATH_RANGE:
break; break;
case XPATH_NODESET: case XPATH_NODESET:
/* /*
@ -575,6 +575,11 @@ xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
case XPATH_POINT: case XPATH_POINT:
ret->user2 = end->user; ret->user2 = end->user;
ret->index2 = end->index; ret->index2 = end->index;
break;
case XPATH_RANGE:
ret->user2 = end->user2;
ret->index2 = end->index2;
break;
case XPATH_NODESET: { case XPATH_NODESET: {
ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1]; ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
ret->index2 = -1; ret->index2 = -1;
@ -1029,6 +1034,15 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
const xmlChar *left = CUR_PTR; const xmlChar *left = CUR_PTR;
CUR_PTR = buffer; CUR_PTR = buffer;
/*
* To evaluate an xpointer scheme element (4.3) we need:
* context initialized to the root
* context position initalized to 1
* context size initialized to 1
*/
ctxt->context->node = (xmlNodePtr)ctxt->context->doc;
ctxt->context->proximityPosition = 1;
ctxt->context->contextSize = 1;
xmlXPathEvalExpr(ctxt); xmlXPathEvalExpr(ctxt);
CUR_PTR=left; CUR_PTR=left;
} else if (xmlStrEqual(name, (xmlChar *) "element")) { } else if (xmlStrEqual(name, (xmlChar *) "element")) {