[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [xml] Regarding Malloc Failure Handling--Patch for Parser.c



On Sat, Mar 29, 2008 at 09:32:46AM +0530, Ashwin wrote:
> >  Yes memory allocation failures should be handled, at least be reported,
> > and of course not leaking or crashing. However it's really hard to
> perfectly
> >handle out of memory failures.
> >  We really need to fix leaks or crashes and report the error though the
> > API, anything beyond that is nice but less critical. If the application >
> chose to ignore the memory error, nothing can be done to save it anyway.
> Hi,
> I am attaching a patch for some memory leak fixes in malloc failure
> scenarios, also adding checks where malloc return is not checked for
> NULL(parser.c). Please let me know if the changes are ok.

  it's right in general, except on need to use xmlFree() and not free()
directly in the library

>   	    goto mem_error;
>   	defaults->nbAttrs = 0;
>   	defaults->maxAttrs = 4;
> ! 	if(xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix, defaults, NULL) < 0){
> !          free(defaults);

  xmlFree()

> !          goto mem_error;
> !          }
>       } else if (defaults->nbAttrs >= defaults->maxAttrs) {
>           xmlDefAttrsPtr temp;
>   
> *************** xmlParserHandlePEReference(xmlParserCtxt
> *** 2289,2297 ****
>   #define growBuffer(buffer) {						\
>       xmlChar *tmp;							\
>       buffer##_size *= 2;							\
> !     tmp = (xmlChar *)							\
> !     		xmlRealloc(buffer, buffer##_size * sizeof(xmlChar));	\
> !     if (tmp == NULL) goto mem_error;					\
>       buffer = tmp;							\
>   }
>   
> --- 2296,2306 ----
>   #define growBuffer(buffer) {						\
>       xmlChar *tmp;							\
>       buffer##_size *= 2;							\
> !     tmp = (xmlChar *) xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \
> !     if (tmp == NULL) {						\
> ! 	xmlFree(buffer);						\
> ! 	goto mem_error;							\
> !     }									\
>       buffer = tmp;							\
>   }

  That looks wrong to me, I would expect the code to free up the buffer
in the mem_error code path, no do that in the macro, i did that in the 2
functions.

> *************** xmlStringLenDecodeEntities(xmlParserCtxt
> *** 2321,2326 ****
> --- 2330,2336 ----
>       int buffer_size = 0;
>   
>       xmlChar *current = NULL;
> +     xmlChar *rep = NULL;
[...]
>   
>   mem_error:
> +     if (rep != NULL)
> +     {
> +         xmlFree(rep);
> +     }
>       xmlErrMemory(ctxt, NULL);
>       return(NULL);
>   }

  hum, right the rep/mem_error goto was a problem, good catch

> *************** xmlSplitQName(xmlParserCtxtPtr ctxt, con
> *** 2634,2640 ****
>   		tmp = (xmlChar *) xmlRealloc(buffer,
>   						max * sizeof(xmlChar));
>   		if (tmp == NULL) {
> ! 		    xmlFree(tmp);
>   		    xmlErrMemory(ctxt, NULL);
>   		    return(NULL);
>   		}
> --- 2650,2656 ----
>   		tmp = (xmlChar *) xmlRealloc(buffer,
>   						max * sizeof(xmlChar));
>   		if (tmp == NULL) {
> ! 		    xmlFree(buffer);
>   		    xmlErrMemory(ctxt, NULL);
>   		    return(NULL);
>   		}

  right !

> *************** static xmlChar *
> *** 3197,3202 ****
> --- 3213,3219 ----
>   xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
>       xmlChar limit = 0;
>       xmlChar *buf = NULL;
> +     xmlChar *rep = NULL;

  Same problem, yes

> *************** xmlParseElementChildrenContentDecl (xmlP
> *** 5471,5476 ****
> --- 5504,5510 ----
>   		return(NULL);
>   	    }
>   	    last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
> +         if (last == NULL) return NULL;
>   	    if (RAW == '?') {
>   		last->ocur = XML_ELEMENT_CONTENT_OPT;
>   		NEXT;

  i think you may leak ret here, so I changed that accordingly

> *************** xmlParseVersionNum(xmlParserCtxtPtr ctxt
> *** 8980,8985 ****
> --- 9014,9020 ----
>   	    size *= 2;
>   	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
>   	    if (tmp == NULL) {
> + 	    xmlFree(buf);
>   		xmlErrMemory(ctxt, NULL);
>   		return(NULL);
>   	    }

  Right,

  so I applied manually all changes, modifying a few things, might be worth
re-checking from SVN head (rev 3720),

  thanks !

Daniel

-- 
Red Hat Virtualization group http://redhat.com/virtualization/
Daniel Veillard      | virtualization library  http://libvirt.org/
veillard redhat com  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine  http://rpmfind.net/


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]