[Expat-CVS] expat/lib expat.h,1.30,1.31 xmlparse.c,1.60,1.61
Karl Waclawek
kwaclaw@users.sourceforge.net
Wed Aug 21 13:01:02 2002
Update of /cvsroot/expat/expat/lib
In directory usw-pr-cvs1:/tmp/cvs-serv28814
Modified Files:
expat.h xmlparse.c
Log Message:
Applied patch for bug #596931: XML_ParseReset and memory leaks.
Index: expat.h
===================================================================
RCS file: /cvsroot/expat/expat/lib/expat.h,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- expat.h 2 Aug 2002 19:40:09 -0000 1.30
+++ expat.h 21 Aug 2002 20:00:09 -0000 1.31
@@ -190,11 +190,12 @@
/* Prepare a parser object to be re-used. This is particularly
valuable when memory allocation overhead is disproportionatly high,
such as when a large number of small documnents need to be parsed.
- All handlers are cleared from the parser.
+ All handlers are cleared from the parser, except for the
+ unknownEncodingHandler.
Added in Expat 1.95.3.
*/
-XMLPARSEAPI(int)
+XMLPARSEAPI(XML_Bool)
XML_ParserReset(XML_Parser parser, const XML_Char *encoding);
/* atts is array of name/value pairs, terminated by 0;
Index: xmlparse.c
===================================================================
RCS file: /cvsroot/expat/expat/lib/xmlparse.c,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -d -r1.60 -r1.61
--- xmlparse.c 2 Aug 2002 19:44:09 -0000 1.60
+++ xmlparse.c 21 Aug 2002 20:00:09 -0000 1.61
@@ -339,6 +339,7 @@
static void normalizePublicId(XML_Char *s);
static void dtdInit(DTD *, XML_Parser parser);
+static void dtdReset(DTD *, XML_Parser parser); /* do not call if parentParser != NULL */
static void dtdDestroy(DTD *, XML_Parser parser);
static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser);
@@ -354,6 +355,7 @@
static void hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite *ms);
+static void hashTableClear(HASH_TABLE *);
static void hashTableDestroy(HASH_TABLE *);
static void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
static NAMED *hashTableIterNext(HASH_TABLE_ITER *);
@@ -379,7 +381,7 @@
const char *ptr,
const char *end);
-static XML_Bool parserInit(XML_Parser parser, const XML_Char *encodingName);
+static void parserInit(XML_Parser parser, const XML_Char *encodingName);
#define poolStart(pool) ((pool)->start)
#define poolEnd(pool) ((pool)->ptr)
@@ -661,18 +663,26 @@
return NULL;
}
dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
+
freeBindingList = NULL;
- inheritedBindings = NULL;
freeTagList = NULL;
+ groupSize = 0;
+ groupConnector = NULL;
+
+ unknownEncodingHandler = NULL;
+ unknownEncodingHandlerData = NULL;
+
namespaceSeparator = '!';
ns = XML_FALSE;
ns_triplets = XML_FALSE;
+
+ parserInit(parser, encodingName);
+ dtdInit(&dtd, parser);
poolInit(&tempPool, &(((Parser *) parser)->m_mem));
poolInit(&temp2Pool, &(((Parser *) parser)->m_mem));
- if (!parserInit(parser, encodingName) || !atts
- || !dataBuf || (encodingName && !protocolEncodingName)) {
+ if (!atts || !dataBuf || (encodingName && !protocolEncodingName)) {
XML_ParserFree(parser);
return NULL;
}
@@ -694,7 +704,7 @@
return parser;
}
-static XML_Bool
+static void
parserInit(XML_Parser parser, const XML_Char *encodingName)
{
processor = prologInitProcessor;
@@ -724,7 +734,6 @@
externalEntityRefHandler = NULL;
externalEntityRefHandlerArg = parser;
skippedEntityHandler = NULL;
- unknownEncodingHandler = NULL;
elementDeclHandler = NULL;
attlistDeclHandler = NULL;
entityDeclHandler = NULL;
@@ -752,33 +761,56 @@
openInternalEntities = 0;
defaultExpandInternalEntities = XML_TRUE;
tagLevel = 0;
- tagStack = 0;
+ tagStack = NULL;
+ inheritedBindings = NULL;
nSpecifiedAtts = 0;
- groupSize = 0;
- groupConnector = NULL;
unknownEncodingMem = NULL;
unknownEncodingRelease = NULL;
unknownEncodingData = NULL;
- unknownEncodingHandlerData = NULL;
parentParser = NULL;
#ifdef XML_DTD
isParamEntity = XML_FALSE;
paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
#endif
- dtdInit(&dtd, parser);
- return XML_TRUE;
}
-int
+/* moves list of bindings to freeBindingList */
+void moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
+{
+ while (bindings) {
+ BINDING *b = bindings;
+ bindings = bindings->nextTagBinding;
+ b->nextTagBinding = freeBindingList;
+ freeBindingList = b;
+ }
+}
+
+XML_Bool
XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
{
- if (parentParser) return 0;
-#ifdef XML_DTD
- if (dtd.scaffold) dtdDestroy(&dtd, parser);
-#endif
+ TAG *tStk;
+ if (parentParser)
+ return XML_FALSE;
+ /* move tagStack to freeTagList */
+ tStk = tagStack;
+ while (tStk) {
+ TAG *tag = tStk;
+ tStk = tStk->parent;
+ tag->parent = freeTagList;
+ moveToFreeBindingList(parser, tag->bindings);
+ tag->bindings = NULL;
+ freeTagList = tag;
+ }
+ moveToFreeBindingList(parser, inheritedBindings);
+ if (unknownEncodingMem)
+ FREE(unknownEncodingMem);
+ if (unknownEncodingRelease)
+ unknownEncodingRelease(unknownEncodingData);
+ parserInit(parser, encodingName);
+ dtdReset(&dtd, parser);
poolClear(&tempPool);
poolClear(&temp2Pool);
- return parserInit(parser, encodingName);
+ return XML_TRUE;
}
int
@@ -1260,10 +1292,10 @@
XmlUpdatePosition(encoding, positionPtr, end, &position);
nLeftOver = s + len - end;
if (nLeftOver) {
- if (buffer == 0 || nLeftOver > bufferLim - buffer) {
+ if (buffer == NULL || nLeftOver > bufferLim - buffer) {
/* FIXME avoid integer overflow */
char *temp;
- temp = buffer == 0 ? MALLOC(len * 2) : REALLOC(buffer, len * 2);
+ temp = buffer == NULL ? MALLOC(len * 2) : REALLOC(buffer, len * 2);
if (temp == NULL) {
errorCode = XML_ERROR_NO_MEMORY;
return XML_STATUS_ERROR;
@@ -4618,6 +4650,39 @@
#endif /* XML_DTD */
static void
+dtdReset(DTD *p, XML_Parser parser)
+{
+ HASH_TABLE_ITER iter;
+ hashTableIterInit(&iter, &(p->elementTypes));
+ for (;;) {
+ ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+ if (!e)
+ break;
+ if (e->allocDefaultAtts != 0)
+ FREE(e->defaultAtts);
+ }
+ hashTableClear(&(p->generalEntities));
+#ifdef XML_DTD
+ hashTableClear(&(p->paramEntities));
+#endif /* XML_DTD */
+ hashTableClear(&(p->elementTypes));
+ hashTableClear(&(p->attributeIds));
+ hashTableClear(&(p->prefixes));
+ poolClear(&(p->pool));
+#ifdef XML_DTD
+ poolClear(&(p->entityValuePool));
+#endif /* XML_DTD */
+ if (p->scaffIndex) {
+ FREE(p->scaffIndex);
+ p->scaffIndex = NULL;
+ }
+ if (p->scaffold) {
+ FREE(p->scaffold);
+ p->scaffold = NULL;
+ }
+}
+
+static void
dtdDestroy(DTD *p, XML_Parser parser)
{
HASH_TABLE_ITER iter;
@@ -4933,6 +4998,21 @@
}
static void
+hashTableClear(HASH_TABLE *table)
+{
+ size_t i;
+ for (i = 0; i < table->size; i++) {
+ NAMED *p = table->v[i];
+ if (p) {
+ table->mem->free_fcn(p);
+ table->v[i] = NULL;
+ }
+ }
+ table->usedLim = table->size / 2;
+ table->used = 0;
+}
+
+static void
hashTableDestroy(HASH_TABLE *table)
{
size_t i;
@@ -4951,7 +5031,7 @@
p->size = 0;
p->usedLim = 0;
p->used = 0;
- p->v = 0;
+ p->v = NULL;
p->mem = ms;
}
@@ -5013,17 +5093,12 @@
pool->mem->free_fcn(p);
p = tem;
}
- pool->blocks = NULL;
p = pool->freeBlocks;
while (p) {
BLOCK *tem = p->next;
pool->mem->free_fcn(p);
p = tem;
}
- pool->freeBlocks = NULL;
- pool->ptr = NULL;
- pool->start = NULL;
- pool->end = NULL;
}
static XML_Char *