msi: fix leak in cond.y

Nathan Gallaher ngallaher at deepthought.org
Thu Dec 17 21:33:32 CST 2009


If parsing failed, any allocated strings would be leaked. Keep track of 
them and then free them all when the parser terminates.
-------------- next part --------------
From 090efff1075759f065db7935d7bf1fa50a80d4ae Mon Sep 17 00:00:00 2001
From: Nathan Gallaher <ngallaher at deepthought.org>
Date: Thu, 17 Dec 2009 22:27:33 -0500
Subject: msi: queue dynamically allocated strings in cond.y for garbage collection

Previously, if parsing failed, any dynamically allocated string would
be leaked.
---
 dlls/msi/cond.y |   77 +++++++++++++++++++++++++++++-------------------------
 1 files changed, 41 insertions(+), 36 deletions(-)

diff --git a/dlls/msi/cond.y b/dlls/msi/cond.y
index c2a1737..9a66e0b 100644
--- a/dlls/msi/cond.y
+++ b/dlls/msi/cond.y
@@ -40,6 +40,7 @@
 #include "msiserver.h"
 #include "wine/debug.h"
 #include "wine/unicode.h"
+#include "wine/list.h"
 
 #define YYLEX_PARAM info
 #define YYPARSE_PARAM info
@@ -54,6 +55,7 @@ typedef struct tag_yyinput
     LPCWSTR str;
     INT    n;
     MSICONDITION result;
+    struct list mem;
 } COND_input;
 
 struct cond_str {
@@ -61,22 +63,14 @@ struct cond_str {
     INT len;
 };
 
-static LPWSTR COND_GetString( const struct cond_str *str );
-static LPWSTR COND_GetLiteral( const struct cond_str *str );
+static LPWSTR COND_GetString( void *info, const struct cond_str *str );
+static LPWSTR COND_GetLiteral( void *info, const struct cond_str *str );
 static int cond_lex( void *COND_lval, COND_input *info);
 
 static INT compare_int( INT a, INT operator, INT b );
 static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert );
 
-static INT compare_and_free_strings( LPWSTR a, INT op, LPWSTR b, BOOL convert )
-{
-    INT r;
-
-    r = compare_string( a, op, b, convert );
-    msi_free( a );
-    msi_free( b );
-    return r;
-}
+static void *cond_alloc( void *info, unsigned int sz );
 
 static BOOL num_from_prop( LPCWSTR p, INT *val )
 {
@@ -189,7 +183,6 @@ boolean_factor:
   | value_s
         {
             $$ = ($1 && $1[0]) ? 1 : 0;
-            msi_free($1);
         }
   | value_i operator value_i
         {
@@ -202,7 +195,6 @@ boolean_factor:
                 $$ = compare_int( num, $2, $3 );
             else 
                 $$ = ($2 == COND_NE || $2 == COND_INE );
-            msi_free($1);
         }
   | value_i operator symbol_s
         {
@@ -211,33 +203,30 @@ boolean_factor:
                 $$ = compare_int( $1, $2, num );
             else 
                 $$ = ($2 == COND_NE || $2 == COND_INE );
-            msi_free($3);
         }
   | symbol_s operator symbol_s
         {
-            $$ = compare_and_free_strings( $1, $2, $3, TRUE );
+            $$ = compare_string( $1, $2, $3, TRUE );
         }
   | symbol_s operator literal
         {
-            $$ = compare_and_free_strings( $1, $2, $3, TRUE );
+            $$ = compare_string( $1, $2, $3, TRUE );
         }
   | literal operator symbol_s
         {
-            $$ = compare_and_free_strings( $1, $2, $3, TRUE );
+            $$ = compare_string( $1, $2, $3, TRUE );
         }
   | literal operator literal
         {
-            $$ = compare_and_free_strings( $1, $2, $3, FALSE );
+            $$ = compare_string( $1, $2, $3, FALSE );
         }
   | literal operator value_i
         {
             $$ = 0;
-            msi_free($1);
         }
   | value_i operator literal
         {
             $$ = 0;
-            msi_free($3);
         }
   | COND_LPAR expression COND_RPAR
         {
@@ -281,7 +270,7 @@ value_s:
 literal:
     COND_LITER
         {
-            $$ = COND_GetLiteral(&$1);
+            $$ = COND_GetLiteral( info, &$1 );
             if( !$$ )
                 YYABORT;
         }
@@ -299,7 +288,6 @@ value_i:
       
             MSI_GetComponentStateW(cond->package, $2, &install, &action );
             $$ = action;
-            msi_free( $2 );
         }
   | COND_QUESTION identifier
         {
@@ -308,7 +296,6 @@ value_i:
       
             MSI_GetComponentStateW(cond->package, $2, &install, &action );
             $$ = install;
-            msi_free( $2 );
         }
   | COND_AMPER identifier
         {
@@ -321,7 +308,6 @@ value_i:
             else
                 $$ = action;
 
-            msi_free( $2 );
         }
   | COND_EXCLAM identifier
         {
@@ -330,7 +316,6 @@ value_i:
       
             MSI_GetFeatureStateW(cond->package, $2, &install, &action );
             $$ = install;
-            msi_free( $2 );
         }
     ;
 
@@ -340,7 +325,6 @@ symbol_s:
             COND_input* cond = (COND_input*) info;
 
             $$ = msi_dup_property( cond->package, $1 );
-            msi_free( $1 );
         }
     | COND_PERCENT identifier
         {
@@ -348,17 +332,18 @@ symbol_s:
             $$ = NULL;
             if (len++)
             {
-                $$ = msi_alloc( len*sizeof (WCHAR) );
+                $$ = cond_alloc( info, len*sizeof (WCHAR) );
+                if (!$$)
+                    YYABORT;
                 GetEnvironmentVariableW( $2, $$, len );
             }
-            msi_free( $2 );
         }
     ;
 
 identifier:
     COND_IDENT
         {
-            $$ = COND_GetString(&$1);
+            $$ = COND_GetString( info, &$1 );
             if( !$$ )
                 YYABORT;
         }
@@ -367,11 +352,10 @@ identifier:
 integer:
     COND_NUMBER
         {
-            LPWSTR szNum = COND_GetString(&$1);
+            LPWSTR szNum = COND_GetString( info, &$1 );
             if( !szNum )
                 YYABORT;
             $$ = atoiW( szNum );
-            msi_free( szNum );
         }
     ;
 
@@ -691,11 +675,11 @@ static int cond_lex( void *COND_lval, COND_input *cond )
     return rc;
 }
 
-static LPWSTR COND_GetString( const struct cond_str *str )
+static LPWSTR COND_GetString( void *info, const struct cond_str *str )
 {
     LPWSTR ret;
 
-    ret = msi_alloc( (str->len+1) * sizeof (WCHAR) );
+    ret = cond_alloc( info, (str->len+1) * sizeof (WCHAR) );
     if( ret )
     {
         memcpy( ret, str->data, str->len * sizeof(WCHAR));
@@ -705,11 +689,11 @@ static LPWSTR COND_GetString( const struct cond_str *str )
     return ret;
 }
 
-static LPWSTR COND_GetLiteral( const struct cond_str *str )
+static LPWSTR COND_GetLiteral( void *info, const struct cond_str *str )
 {
     LPWSTR ret;
 
-    ret = msi_alloc( (str->len-1) * sizeof (WCHAR) );
+    ret = cond_alloc( info, (str->len-1) * sizeof (WCHAR) );
     if( ret )
     {
         memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) );
@@ -719,6 +703,20 @@ static LPWSTR COND_GetLiteral( const struct cond_str *str )
     return ret;
 }
 
+static void *cond_alloc( void *info, unsigned int sz )
+{
+    COND_input *cond = (COND_input*) info;
+    struct list *mem;
+    mem = msi_alloc( sizeof (struct list) + sz);
+    if (!mem)
+    {
+        return NULL;
+    }
+
+    list_add_tail( &cond->mem, mem );
+    return &mem[1];
+}
+
 static int cond_error(const char *str)
 {
     TRACE("%s\n", str );
@@ -729,6 +727,7 @@ MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition )
 {
     COND_input cond;
     MSICONDITION r;
+    struct list *ptr, *t;
 
     TRACE("%s\n", debugstr_w( szCondition ) );
 
@@ -739,12 +738,18 @@ MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition )
     cond.str   = szCondition;
     cond.n     = 0;
     cond.result = MSICONDITION_ERROR;
-    
+    list_init( &cond.mem );
+
     if ( !cond_parse( &cond ) )
         r = cond.result;
     else
         r = MSICONDITION_ERROR;
 
+    LIST_FOR_EACH_SAFE( ptr, t, &cond.mem )
+    {
+        msi_free( ptr );
+    }
+
     TRACE("%i <- %s\n", r, debugstr_w(szCondition));
     return r;
 }
-- 
1.6.0.4



More information about the wine-patches mailing list