On Wed, Apr 02, 2008 at 11:38:48AM +0530, Ashwin wrote:
>> Oops, forgot to attach the patch!!! Sorry
>> 
>> Hi,
>> 
>>    I am attaching a patch for memleak in InputPush function in case
>>realloc
>> fails. realloc was being done on the original pointer, and inputstream
>> was not being freed in case of failure. Also returning from functions >>
>> calling xmlPushInput if memory failure has occurred (Not sure whther this
>> is required in all cases).

> While the description sounds good, the patch didn't apply to CVS, could 
>you double-check the patch please ?
        
Hi,
   Sorry for the delay in reply. I didn't understand, you mean the patch was
wrong? Anyway I am attaching patch again, please let me know if it is ok...
Basically checking if a mem error has occurred in inputPush and returning
from there if it has....

> 
> Another query is for a lot of places where Inputpush function is invoked
the
> return value is not checked, from what I could make out this is because at
> the time of context creation the number of input streams is set to 5, and
> since push is being called directly afterwards, the number of streams will
> not be more than 5 and thus the realloc block inside inputPush will not be
> hit. So perhaps that is why memory failure is not expected in those paths.


>>  Hum, no, I guess it's an oversight which should be fixed too.

   Inside inputPush function if realloc fails I am now freeing the
inputstream, however I am not 100% sure this is the correct way to go about
it... 

Regards
Ashwin
*** parser.c    2008-04-23 21:20:18.000000000 +0530
--- parserfix.c 2008-04-24 14:01:37.000000000 +0530
*************** inputPush(xmlParserCtxtPtr ctxt, xmlPars
*** 1358,1363 ****
--- 1358,1366 ----
                                               sizeof(ctxt->inputTab[0]));
          if (ctxt->inputTab == NULL) {
              xmlErrMemory(ctxt, NULL);
+             xmlFreeInputStream(value);
+                       ctxt->inputMax /= 2;
+                    value = NULL;              
              return (0);
          }
      }
*************** static int spacePush(xmlParserCtxtPtr ct
*** 1594,1599 ****
--- 1597,1603 ----
                                 ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
          if (tmp == NULL) {
            xmlErrMemory(ctxt, NULL);
+           ctxt->spaceMax /=2;
            return(0);
        }
        ctxt->spaceTab = tmp;
*************** xmlParserHandlePEReference(xmlParserCtxt
*** 2244,2249 ****
--- 2248,2255 ----
            } else if (ctxt->input->free != deallocblankswrapper) {
                    input = xmlNewBlanksWrapperInputStream(ctxt, entity);
                    xmlPushInput(ctxt, input);
+                    if (ctxt->errNo == XML_ERR_NO_MEMORY)
+                       return;
            } else {
                if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
                    (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
*************** xmlParserHandlePEReference(xmlParserCtxt
*** 2257,2262 ****
--- 2263,2270 ----
                     */
                    input = xmlNewEntityInputStream(ctxt, entity);
                    xmlPushInput(ctxt, input);
+                   if (ctxt->errNo == XML_ERR_NO_MEMORY)
+                       return;
  
                    /* 
                     * Get the 4 first bytes and decode the charset
*************** xmlParsePEReference(xmlParserCtxtPtr ctx
*** 6962,6967 ****
--- 6970,6977 ----
                          input =
                              xmlNewBlanksWrapperInputStream(ctxt, entity);
                          xmlPushInput(ctxt, input);
+                          if (ctxt->errNo == XML_ERR_NO_MEMORY)
+                                   return;
                      } else {
                          /*
                           * TODO !!!
*************** xmlParsePEReference(xmlParserCtxtPtr ctx
*** 6970,6975 ****
--- 6980,6987 ----
                           */
                          input = xmlNewEntityInputStream(ctxt, entity);
                          xmlPushInput(ctxt, input);
+                          if (ctxt->errNo == XML_ERR_NO_MEMORY)
+                               return;
                          if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) 
&&
                            (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
                            (IS_BLANK_CH(NXT(5)))) {
*************** xmlLoadEntityContent(xmlParserCtxtPtr ct
*** 7045,7050 ****
--- 7057,7066 ----
       * saving to the buffer until the end of the entity or an error
       */
      xmlPushInput(ctxt, input);
+      if (ctxt->errNo == XML_ERR_NO_MEMORY) {
+           xmlBufferFree(buf); 
+          return(-1);
+         }
      GROW;
      c = CUR_CHAR(l);
      while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
*************** xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlP
*** 11246,11251 ****
--- 11262,11271 ----
       * plug some encoding conversion routines here.
       */
      xmlPushInput(ctxt, pinput);
+      if (ctxt->errNo == XML_ERR_NO_MEMORY) {
+           xmlFreeParserCtxt(ctxt);
+           return;
+         }
      if (enc != XML_CHAR_ENCODING_NONE) {
          xmlSwitchEncoding(ctxt, enc);
      }
*************** xmlSAXParseDTD(xmlSAXHandlerPtr sax, con
*** 11375,11380 ****
--- 11395,11407 ----
       * plug some encoding conversion routines here.
       */
      xmlPushInput(ctxt, input);
+      if (ctxt->errNo == XML_ERR_NO_MEMORY) {
+         if (sax != NULL) ctxt->sax = NULL;
+               xmlFreeParserCtxt(ctxt);
+               if (systemIdCanonic != NULL)
+                   xmlFree(systemIdCanonic);
+         return(NULL);
+         }
      if ((ctxt->input->end - ctxt->input->cur) >= 4) {
        enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
        xmlSwitchEncoding(ctxt, enc);
_______________________________________________
xml mailing list, project page  http://xmlsoft.org/
[email protected]
http://mail.gnome.org/mailman/listinfo/xml

Reply via email to