diff --git a/dlls/msi/cond.y b/dlls/msi/cond.y index 062af07..7eb48c5 100644 --- a/dlls/msi/cond.y +++ b/dlls/msi/cond.y @@ -67,13 +67,13 @@ static int cond_lex( void *COND_lval, COND_input *info); static const WCHAR szEmpty[] = { 0 }; static INT compare_int( INT a, INT operator, INT b ); -static INT compare_string( LPCWSTR a, INT operator, LPCWSTR 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 ) +static INT compare_and_free_strings( LPWSTR a, INT op, LPWSTR b, BOOL convert ) { INT r; - r = compare_string( a, op, b ); + r = compare_string( a, op, b, convert ); msi_free( a ); msi_free( b ); return r; @@ -216,19 +216,19 @@ boolean_factor: } | symbol_s operator symbol_s { - $$ = compare_and_free_strings( $1, $2, $3 ); + $$ = compare_and_free_strings( $1, $2, $3, TRUE ); } | symbol_s operator literal { - $$ = compare_and_free_strings( $1, $2, $3 ); + $$ = compare_and_free_strings( $1, $2, $3, TRUE ); } | literal operator symbol_s { - $$ = compare_and_free_strings( $1, $2, $3 ); + $$ = compare_and_free_strings( $1, $2, $3, TRUE ); } | literal operator literal { - $$ = compare_and_free_strings( $1, $2, $3 ); + $$ = compare_and_free_strings( $1, $2, $3, FALSE ); } | literal operator value_i { @@ -408,6 +408,9 @@ static BOOL str_is_number( LPCWSTR str ) { int i; + if (!*str) + return FALSE; + for (i = 0; i < lstrlenW( str ); i++) if (!isdigitW(str[i])) return FALSE; @@ -454,7 +457,7 @@ static INT compare_substring( LPCWSTR a, INT operator, LPCWSTR b ) return 0; } -static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b ) +static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert ) { if (operator >= COND_SS && operator <= COND_RHS) return compare_substring( a, operator, b ); @@ -463,6 +466,9 @@ static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b ) if (!a) a = szEmpty; if (!b) b = szEmpty; + if (convert && str_is_number(a) && str_is_number(b)) + return compare_int( atoiW(a), operator, atoiW(b) ); + /* a or b may be NULL */ switch (operator) { diff --git a/dlls/msi/tests/package.c b/dlls/msi/tests/package.c index 511e3d4..5c8741b 100644 --- a/dlls/msi/tests/package.c +++ b/dlls/msi/tests/package.c @@ -1631,6 +1631,46 @@ static void test_condition(void) r = MsiEvaluateCondition(hpkg, "&nofeature"); ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); + MsiSetProperty(hpkg, "A", "2"); + MsiSetProperty(hpkg, "X", "50"); + + r = MsiEvaluateCondition(hpkg, "2 <= X"); + ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); + + r = MsiEvaluateCondition(hpkg, "A <= X"); + ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); + + r = MsiEvaluateCondition(hpkg, "A <= 50"); + ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); + + MsiSetProperty(hpkg, "X", "50val"); + + r = MsiEvaluateCondition(hpkg, "2 <= X"); + ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); + + r = MsiEvaluateCondition(hpkg, "A <= X"); + ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); + + MsiSetProperty(hpkg, "A", "7"); + MsiSetProperty(hpkg, "X", "50"); + + r = MsiEvaluateCondition(hpkg, "7 <= X"); + ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); + + r = MsiEvaluateCondition(hpkg, "A <= X"); + ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); + + r = MsiEvaluateCondition(hpkg, "A <= 50"); + ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); + + MsiSetProperty(hpkg, "X", "50val"); + + r = MsiEvaluateCondition(hpkg, "2 <= X"); + ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); + + r = MsiEvaluateCondition(hpkg, "A <= X"); + ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); + MsiCloseHandle( hpkg ); DeleteFile(msifile); } -- 1.5.4.3