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