From 68b6e02bfdb9d206d1bd89d0c8650c9b66fcfdab Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Mon, 31 Mar 2008 09:26:00 +0000 Subject: [PATCH] lot of out of memory handling fixes from Ashwin work around a problem with * parser.c: lot of out of memory handling fixes from Ashwin * elfgcchack.h doc/elfgcchack.xsl: work around a problem with xmlDllMain * include/libxml/threads.h: indenting cleanups Daniel svn path=/trunk/; revision=3720 --- ChangeLog | 6 ++++ doc/elfgcchack.xsl | 2 +- elfgcchack.h | 10 ------ include/libxml/threads.h | 30 +++++++++--------- parser.c | 68 ++++++++++++++++++++++++++++++---------- 5 files changed, 73 insertions(+), 43 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1d1416a0..cab04cfb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Mon Mar 31 11:23:19 CEST 2008 Daniel Veillard + + * parser.c: lot of out of memory handling fixes from Ashwin + * elfgcchack.h doc/elfgcchack.xsl: work around a problem with xmlDllMain + * include/libxml/threads.h: indenting cleanups + Mon Mar 31 10:25:37 CEST 2008 Daniel Veillard * parser.c docs/*: trying to clarify even more the xmlCleanupParser() diff --git a/doc/elfgcchack.xsl b/doc/elfgcchack.xsl index 11169f99..1adf340e 100644 --- a/doc/elfgcchack.xsl +++ b/doc/elfgcchack.xsl @@ -106,7 +106,7 @@ extern __typeof (__xmlGenericErrorContext) __xmlGenericErrorContext__internal_al - + #ifdef bottom_ diff --git a/elfgcchack.h b/elfgcchack.h index a17fa97f..e1d21bb2 100644 --- a/elfgcchack.h +++ b/elfgcchack.h @@ -2877,16 +2877,6 @@ extern __typeof (xmlDictSize) xmlDictSize__internal_alias __attribute((visibilit #endif #endif -#ifdef bottom_threads -#undef xmlDllMain -extern __typeof (xmlDllMain) xmlDllMain __attribute((alias("xmlDllMain__internal_alias"))); -#else -#ifndef xmlDllMain -extern __typeof (xmlDllMain) xmlDllMain__internal_alias __attribute((visibility("hidden"))); -#define xmlDllMain xmlDllMain__internal_alias -#endif -#endif - #ifdef bottom_tree #undef xmlDocCopyNode extern __typeof (xmlDocCopyNode) xmlDocCopyNode __attribute((alias("xmlDocCopyNode__internal_alias"))); diff --git a/include/libxml/threads.h b/include/libxml/threads.h index f81f9824..d31f16ac 100644 --- a/include/libxml/threads.h +++ b/include/libxml/threads.h @@ -36,40 +36,40 @@ typedef xmlRMutex *xmlRMutexPtr; #ifdef __cplusplus extern "C" { #endif -XMLPUBFUN xmlMutexPtr XMLCALL +XMLPUBFUN xmlMutexPtr XMLCALL xmlNewMutex (void); -XMLPUBFUN void XMLCALL +XMLPUBFUN void XMLCALL xmlMutexLock (xmlMutexPtr tok); -XMLPUBFUN void XMLCALL +XMLPUBFUN void XMLCALL xmlMutexUnlock (xmlMutexPtr tok); -XMLPUBFUN void XMLCALL +XMLPUBFUN void XMLCALL xmlFreeMutex (xmlMutexPtr tok); -XMLPUBFUN xmlRMutexPtr XMLCALL +XMLPUBFUN xmlRMutexPtr XMLCALL xmlNewRMutex (void); -XMLPUBFUN void XMLCALL +XMLPUBFUN void XMLCALL xmlRMutexLock (xmlRMutexPtr tok); -XMLPUBFUN void XMLCALL +XMLPUBFUN void XMLCALL xmlRMutexUnlock (xmlRMutexPtr tok); -XMLPUBFUN void XMLCALL +XMLPUBFUN void XMLCALL xmlFreeRMutex (xmlRMutexPtr tok); /* * Library wide APIs. */ -XMLPUBFUN void XMLCALL +XMLPUBFUN void XMLCALL xmlInitThreads (void); -XMLPUBFUN void XMLCALL +XMLPUBFUN void XMLCALL xmlLockLibrary (void); -XMLPUBFUN void XMLCALL +XMLPUBFUN void XMLCALL xmlUnlockLibrary(void); -XMLPUBFUN int XMLCALL +XMLPUBFUN int XMLCALL xmlGetThreadId (void); -XMLPUBFUN int XMLCALL +XMLPUBFUN int XMLCALL xmlIsMainThread (void); -XMLPUBFUN void XMLCALL +XMLPUBFUN void XMLCALL xmlCleanupThreads(void); -XMLPUBFUN xmlGlobalStatePtr XMLCALL +XMLPUBFUN xmlGlobalStatePtr XMLCALL xmlGetGlobalState(void); #if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && defined(LIBXML_STATIC_FOR_DLL) diff --git a/parser.c b/parser.c index 2530e60a..44685b4a 100644 --- a/parser.c +++ b/parser.c @@ -1016,7 +1016,11 @@ xmlAddDefAttrs(xmlParserCtxtPtr ctxt, goto mem_error; defaults->nbAttrs = 0; defaults->maxAttrs = 4; - xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix, defaults, NULL); + if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix, + defaults, NULL) < 0) { + xmlFree(defaults); + goto mem_error; + } } else if (defaults->nbAttrs >= defaults->maxAttrs) { xmlDefAttrsPtr temp; @@ -1026,7 +1030,11 @@ xmlAddDefAttrs(xmlParserCtxtPtr ctxt, goto mem_error; defaults = temp; defaults->maxAttrs *= 2; - xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix, defaults, NULL); + if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix, + defaults, NULL) < 0) { + xmlFree(defaults); + goto mem_error; + } } /* @@ -2074,6 +2082,7 @@ xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) { buffer = xmlMallocAtomic(length); if (buffer == NULL) { xmlErrMemory(ctxt, NULL); + xmlFree(input); return(NULL); } buffer [0] = ' '; @@ -2290,7 +2299,7 @@ xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) { xmlChar *tmp; \ buffer##_size *= 2; \ tmp = (xmlChar *) \ - xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \ + xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \ if (tmp == NULL) goto mem_error; \ buffer = tmp; \ } @@ -2321,6 +2330,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, int buffer_size = 0; xmlChar *current = NULL; + xmlChar *rep = NULL; const xmlChar *last; xmlEntityPtr ent; int c,l; @@ -2380,8 +2390,6 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, "predefined entity has no content\n"); } } else if ((ent != NULL) && (ent->content != NULL)) { - xmlChar *rep; - ctxt->depth++; rep = xmlStringDecodeEntities(ctxt, ent->content, what, 0, 0, 0); @@ -2396,6 +2404,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, } } xmlFree(rep); + rep = NULL; } } else if (ent != NULL) { int i = xmlStrlen(ent->name); @@ -2415,8 +2424,6 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, "String decoding PE Reference: %.30s\n", str); ent = xmlParseStringPEReference(ctxt, &str); if (ent != NULL) { - xmlChar *rep; - if (ent->content == NULL) { if (xmlLoadEntityContent(ctxt, ent) < 0) { } @@ -2435,6 +2442,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, } } xmlFree(rep); + rep = NULL; } } } else { @@ -2454,6 +2462,10 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, mem_error: xmlErrMemory(ctxt, NULL); + if (rep != NULL) + xmlFree(rep); + if (buffer != NULL) + xmlFree(buffer); return(NULL); } @@ -2634,7 +2646,7 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) { tmp = (xmlChar *) xmlRealloc(buffer, max * sizeof(xmlChar)); if (tmp == NULL) { - xmlFree(tmp); + xmlFree(buffer); xmlErrMemory(ctxt, NULL); return(NULL); } @@ -2698,7 +2710,7 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) { * for the processing speed. */ max = len * 2; - + buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar)); if (buffer == NULL) { xmlErrMemory(ctxt, NULL); @@ -2724,7 +2736,7 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) { } buffer[len] = 0; } - + if (buffer == NULL) ret = xmlStrndup(buf, len); else { @@ -3197,6 +3209,7 @@ static xmlChar * xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) { xmlChar limit = 0; xmlChar *buf = NULL; + xmlChar *rep = NULL; int len = 0; int buf_size = 0; int c, l, in_space = 0; @@ -3215,7 +3228,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) { xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL); return(NULL); } - + /* * allocate a translation buffer. */ @@ -3280,8 +3293,6 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) { } } else if ((ent != NULL) && (ctxt->replaceEntities != 0)) { - xmlChar *rep; - if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) { rep = xmlStringDecodeEntities(ctxt, ent->content, XML_SUBSTITUTE_REF, @@ -3295,6 +3306,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) { } } xmlFree(rep); + rep = NULL; } } else { if (len > buf_size - 10) { @@ -3315,9 +3327,11 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) { (ent->content != NULL)) { xmlChar *rep; rep = xmlStringDecodeEntities(ctxt, ent->content, - XML_SUBSTITUTE_REF, 0, 0, 0); - if (rep != NULL) + XML_SUBSTITUTE_REF, 0, 0, 0); + if (rep != NULL) { xmlFree(rep); + rep = NULL; + } } /* @@ -3376,6 +3390,10 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) { mem_error: xmlErrMemory(ctxt, NULL); + if (buf != NULL) + xmlFree(buf); + if (rep != NULL) + xmlFree(rep); return(NULL); } @@ -4644,6 +4662,10 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) { (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) { if (ctxt->myDoc == NULL) { ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE); + if (ctxt->myDoc == NULL) { + xmlErrMemory(ctxt, "New Doc failed"); + return; + } } if (ctxt->myDoc->intSubset == NULL) ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc, @@ -4712,6 +4734,10 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) { (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) { if (ctxt->myDoc == NULL) { ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE); + if (ctxt->myDoc == NULL) { + xmlErrMemory(ctxt, "New Doc failed"); + return; + } } if (ctxt->myDoc->intSubset == NULL) @@ -5216,6 +5242,8 @@ xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) { } NEXT; ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA); + if (ret == NULL) + return(NULL); if (RAW == '*') { ret->ocur = XML_ELEMENT_CONTENT_MULT; NEXT; @@ -5471,6 +5499,11 @@ xmlParseElementChildrenContentDecl (xmlParserCtxtPtr ctxt, int inputchk) { return(NULL); } last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT); + if (last == NULL) { + if (ret != NULL) + xmlFreeDocElementContent(ctxt->myDoc, ret); + return(NULL); + } if (RAW == '?') { last->ocur = XML_ELEMENT_CONTENT_OPT; NEXT; @@ -8980,6 +9013,7 @@ xmlParseVersionNum(xmlParserCtxtPtr ctxt) { size *= 2; tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar)); if (tmp == NULL) { + xmlFree(buf); xmlErrMemory(ctxt, NULL); return(NULL); } @@ -8996,11 +9030,11 @@ xmlParseVersionNum(xmlParserCtxtPtr ctxt) { /** * xmlParseVersionInfo: * @ctxt: an XML parser context - * + * * parse the XML version. * * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ") - * + * * [25] Eq ::= S? '=' S? * * Returns the version string, e.g. "1.0"