mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-15 00:27:16 +00:00
msi: Queue dynamically allocated strings in cond.y.
This commit is contained in:
parent
25bee84030
commit
0c437f558c
122
dlls/msi/cond.y
122
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,10 +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( COND_input *info, const struct cond_str *str );
|
||||
static LPWSTR COND_GetLiteral( COND_input *info, const struct cond_str *str );
|
||||
static int cond_lex( void *COND_lval, COND_input *info);
|
||||
|
||||
static void *cond_alloc( COND_input *cond, unsigned int sz );
|
||||
static void *cond_track_mem( COND_input *cond, void *ptr, unsigned int sz );
|
||||
static void cond_free( void *ptr );
|
||||
|
||||
static INT compare_int( INT a, INT operator, INT b );
|
||||
static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert );
|
||||
|
||||
|
@ -73,8 +79,8 @@ 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 );
|
||||
cond_free( a );
|
||||
cond_free( b );
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -189,7 +195,7 @@ boolean_factor:
|
|||
| value_s
|
||||
{
|
||||
$$ = ($1 && $1[0]) ? 1 : 0;
|
||||
msi_free($1);
|
||||
cond_free( $1 );
|
||||
}
|
||||
| value_i operator value_i
|
||||
{
|
||||
|
@ -202,7 +208,7 @@ boolean_factor:
|
|||
$$ = compare_int( num, $2, $3 );
|
||||
else
|
||||
$$ = ($2 == COND_NE || $2 == COND_INE );
|
||||
msi_free($1);
|
||||
cond_free( $1 );
|
||||
}
|
||||
| value_i operator symbol_s
|
||||
{
|
||||
|
@ -211,7 +217,7 @@ boolean_factor:
|
|||
$$ = compare_int( $1, $2, num );
|
||||
else
|
||||
$$ = ($2 == COND_NE || $2 == COND_INE );
|
||||
msi_free($3);
|
||||
cond_free( $3 );
|
||||
}
|
||||
| symbol_s operator symbol_s
|
||||
{
|
||||
|
@ -232,12 +238,12 @@ boolean_factor:
|
|||
| literal operator value_i
|
||||
{
|
||||
$$ = 0;
|
||||
msi_free($1);
|
||||
cond_free( $1 );
|
||||
}
|
||||
| value_i operator literal
|
||||
{
|
||||
$$ = 0;
|
||||
msi_free($3);
|
||||
cond_free( $3 );
|
||||
}
|
||||
| COND_LPAR expression COND_RPAR
|
||||
{
|
||||
|
@ -281,7 +287,8 @@ value_s:
|
|||
literal:
|
||||
COND_LITER
|
||||
{
|
||||
$$ = COND_GetLiteral(&$1);
|
||||
COND_input* cond = (COND_input*) info;
|
||||
$$ = COND_GetLiteral( cond, &$1 );
|
||||
if( !$$ )
|
||||
YYABORT;
|
||||
}
|
||||
|
@ -299,7 +306,7 @@ value_i:
|
|||
|
||||
MSI_GetComponentStateW(cond->package, $2, &install, &action );
|
||||
$$ = action;
|
||||
msi_free( $2 );
|
||||
cond_free( $2 );
|
||||
}
|
||||
| COND_QUESTION identifier
|
||||
{
|
||||
|
@ -308,7 +315,7 @@ value_i:
|
|||
|
||||
MSI_GetComponentStateW(cond->package, $2, &install, &action );
|
||||
$$ = install;
|
||||
msi_free( $2 );
|
||||
cond_free( $2 );
|
||||
}
|
||||
| COND_AMPER identifier
|
||||
{
|
||||
|
@ -321,7 +328,7 @@ value_i:
|
|||
else
|
||||
$$ = action;
|
||||
|
||||
msi_free( $2 );
|
||||
cond_free( $2 );
|
||||
}
|
||||
| COND_EXCLAM identifier
|
||||
{
|
||||
|
@ -330,7 +337,7 @@ value_i:
|
|||
|
||||
MSI_GetFeatureStateW(cond->package, $2, &install, &action );
|
||||
$$ = install;
|
||||
msi_free( $2 );
|
||||
cond_free( $2 );
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -338,27 +345,37 @@ symbol_s:
|
|||
identifier
|
||||
{
|
||||
COND_input* cond = (COND_input*) info;
|
||||
UINT len;
|
||||
|
||||
$$ = msi_dup_property( cond->package, $1 );
|
||||
msi_free( $1 );
|
||||
if ($$)
|
||||
{
|
||||
len = (lstrlenW($$) + 1) * sizeof (WCHAR);
|
||||
$$ = cond_track_mem( cond, $$, len );
|
||||
}
|
||||
cond_free( $1 );
|
||||
}
|
||||
| COND_PERCENT identifier
|
||||
{
|
||||
COND_input* cond = (COND_input*) info;
|
||||
UINT len = GetEnvironmentVariableW( $2, NULL, 0 );
|
||||
$$ = NULL;
|
||||
if (len++)
|
||||
{
|
||||
$$ = msi_alloc( len*sizeof (WCHAR) );
|
||||
$$ = cond_alloc( cond, len*sizeof (WCHAR) );
|
||||
if( !$$ )
|
||||
YYABORT;
|
||||
GetEnvironmentVariableW( $2, $$, len );
|
||||
}
|
||||
msi_free( $2 );
|
||||
cond_free( $2 );
|
||||
}
|
||||
;
|
||||
|
||||
identifier:
|
||||
COND_IDENT
|
||||
{
|
||||
$$ = COND_GetString(&$1);
|
||||
COND_input* cond = (COND_input*) info;
|
||||
$$ = COND_GetString( cond, &$1 );
|
||||
if( !$$ )
|
||||
YYABORT;
|
||||
}
|
||||
|
@ -367,11 +384,12 @@ identifier:
|
|||
integer:
|
||||
COND_NUMBER
|
||||
{
|
||||
LPWSTR szNum = COND_GetString(&$1);
|
||||
COND_input* cond = (COND_input*) info;
|
||||
LPWSTR szNum = COND_GetString( cond, &$1 );
|
||||
if( !szNum )
|
||||
YYABORT;
|
||||
$$ = atoiW( szNum );
|
||||
msi_free( szNum );
|
||||
cond_free( szNum );
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -691,11 +709,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( COND_input *cond, const struct cond_str *str )
|
||||
{
|
||||
LPWSTR ret;
|
||||
|
||||
ret = msi_alloc( (str->len+1) * sizeof (WCHAR) );
|
||||
ret = cond_alloc( cond, (str->len+1) * sizeof (WCHAR) );
|
||||
if( ret )
|
||||
{
|
||||
memcpy( ret, str->data, str->len * sizeof(WCHAR));
|
||||
|
@ -705,11 +723,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( COND_input *cond, const struct cond_str *str )
|
||||
{
|
||||
LPWSTR ret;
|
||||
|
||||
ret = msi_alloc( (str->len-1) * sizeof (WCHAR) );
|
||||
ret = cond_alloc( cond, (str->len-1) * sizeof (WCHAR) );
|
||||
if( ret )
|
||||
{
|
||||
memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) );
|
||||
|
@ -719,6 +737,48 @@ static LPWSTR COND_GetLiteral( const struct cond_str *str )
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void *cond_alloc( COND_input *cond, unsigned int sz )
|
||||
{
|
||||
struct list *mem;
|
||||
|
||||
mem = msi_alloc( sizeof (struct list) + sz );
|
||||
if( !mem )
|
||||
return NULL;
|
||||
|
||||
list_add_head( &(cond->mem), mem );
|
||||
return mem + 1;
|
||||
}
|
||||
|
||||
static void *cond_track_mem( COND_input *cond, void *ptr, unsigned int sz )
|
||||
{
|
||||
void *new_ptr;
|
||||
|
||||
if( !ptr )
|
||||
return ptr;
|
||||
|
||||
new_ptr = cond_alloc( cond, sz );
|
||||
if( !new_ptr )
|
||||
{
|
||||
msi_free( ptr );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy( new_ptr, ptr, sz );
|
||||
msi_free( ptr );
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
static void cond_free( void *ptr )
|
||||
{
|
||||
struct list *mem = (struct list *)ptr - 1;
|
||||
|
||||
if( ptr )
|
||||
{
|
||||
list_remove( mem );
|
||||
msi_free( mem );
|
||||
}
|
||||
}
|
||||
|
||||
static int cond_error(const char *str)
|
||||
{
|
||||
TRACE("%s\n", str );
|
||||
|
@ -729,6 +789,7 @@ MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition )
|
|||
{
|
||||
COND_input cond;
|
||||
MSICONDITION r;
|
||||
struct list *mem, *safety;
|
||||
|
||||
TRACE("%s\n", debugstr_w( szCondition ) );
|
||||
|
||||
|
@ -739,12 +800,23 @@ 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( mem, safety, &cond.mem )
|
||||
{
|
||||
/* The tracked memory lives directly after the list struct */
|
||||
void *ptr = mem + 1;
|
||||
if ( r != MSICONDITION_ERROR )
|
||||
WARN( "condition parser failed to free up some memory: %p\n", ptr );
|
||||
cond_free( ptr );
|
||||
}
|
||||
|
||||
TRACE("%i <- %s\n", r, debugstr_w(szCondition));
|
||||
return r;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue