Commit 6a520c0b authored by James Hawkins's avatar James Hawkins Committed by Alexandre Julliard

msi: Add handling for MsiEvaluateCondition's substring operators.

parent 762a13eb
...@@ -396,8 +396,61 @@ static WCHAR *strstriW( const WCHAR *str, const WCHAR *sub ) ...@@ -396,8 +396,61 @@ static WCHAR *strstriW( const WCHAR *str, const WCHAR *sub )
return r; return r;
} }
static BOOL str_is_number( LPCWSTR str )
{
int i;
for (i = 0; i < lstrlenW( str ); i++)
if (!isdigitW(str[i]))
return FALSE;
return TRUE;
}
static INT compare_substring( LPCWSTR a, INT operator, LPCWSTR b )
{
int lhs, rhs;
/* substring operators return 0 if LHS is missing */
if (!a || !*a)
return 0;
/* substring operators return 1 if RHS is missing */
if (!b || !*b)
return 1;
/* if both strings contain only numbers, use integer comparison */
lhs = atoiW(a);
rhs = atoiW(b);
if (str_is_number(a) && str_is_number(b))
return compare_int( lhs, operator, rhs );
switch (operator)
{
case COND_SS:
return strstrW( a, b ) ? 1 : 0;
case COND_ISS:
return strstriW( a, b ) ? 1 : 0;
case COND_LHS:
return 0 == strncmpW( a, b, lstrlenW( b ) );
case COND_RHS:
return 0 == lstrcmpW( a + (lstrlenW( a ) - lstrlenW( b )), b );
case COND_ILHS:
return 0 == strncmpiW( a, b, lstrlenW( b ) );
case COND_IRHS:
return 0 == lstrcmpiW( a + (lstrlenW( a ) - lstrlenW( b )), b );
default:
ERR("invalid substring operator\n");
return 0;
}
return 0;
}
static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b ) static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b )
{ {
if (operator >= COND_SS && operator <= COND_RHS)
return compare_substring( a, operator, b );
/* null and empty string are equivalent */ /* null and empty string are equivalent */
if (!a) a = szEmpty; if (!a) a = szEmpty;
if (!b) b = szEmpty; if (!b) b = szEmpty;
...@@ -417,8 +470,6 @@ static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b ) ...@@ -417,8 +470,6 @@ static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b )
return -1 != lstrcmpW( a, b ); return -1 != lstrcmpW( a, b );
case COND_LE: case COND_LE:
return 1 != lstrcmpW( a, b ); return 1 != lstrcmpW( a, b );
case COND_SS: /* substring */
return strstrW( a, b ) ? 1 : 0;
case COND_ILT: case COND_ILT:
return -1 == lstrcmpiW( a, b ); return -1 == lstrcmpiW( a, b );
case COND_IGT: case COND_IGT:
...@@ -431,16 +482,8 @@ static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b ) ...@@ -431,16 +482,8 @@ static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b )
return -1 != lstrcmpiW( a, b ); return -1 != lstrcmpiW( a, b );
case COND_ILE: case COND_ILE:
return 1 != lstrcmpiW( a, b ); return 1 != lstrcmpiW( a, b );
case COND_ISS:
return strstriW( a, b ) ? 1 : 0;
case COND_LHS:
case COND_RHS:
case COND_ILHS:
case COND_IRHS:
ERR("unimplemented string comparison\n");
break;
default: default:
ERR("invalid integer operator\n"); ERR("invalid string operator\n");
return 0; return 0;
} }
return 0; return 0;
...@@ -508,10 +551,10 @@ static int COND_GetOperator( COND_input *cond ) ...@@ -508,10 +551,10 @@ static int COND_GetOperator( COND_input *cond )
{ {'>','=',0}, COND_GE }, { {'>','=',0}, COND_GE },
{ {'>','<',0}, COND_SS }, { {'>','<',0}, COND_SS },
{ {'<','<',0}, COND_LHS }, { {'<','<',0}, COND_LHS },
{ {'>',0}, COND_GT },
{ {'<','>',0}, COND_NE }, { {'<','>',0}, COND_NE },
{ {'<','=',0}, COND_LE }, { {'<','=',0}, COND_LE },
{ {'>','>',0}, COND_RHS }, { {'>','>',0}, COND_RHS },
{ {'>',0}, COND_GT },
{ {'<',0}, COND_LT }, { {'<',0}, COND_LT },
{ {0}, 0 } { {0}, 0 }
}; };
......
...@@ -1043,10 +1043,7 @@ static void test_condition(void) ...@@ -1043,10 +1043,7 @@ static void test_condition(void)
MsiSetProperty(hpkg, "one", "1234"); MsiSetProperty(hpkg, "one", "1234");
MsiSetProperty(hpkg, "two", "1"); MsiSetProperty(hpkg, "two", "1");
r = MsiEvaluateCondition(hpkg, "one >< two"); r = MsiEvaluateCondition(hpkg, "one >< two");
todo_wine ok( r == MSICONDITION_FALSE, "wrong return val\n");
{
ok( r == MSICONDITION_FALSE, "wrong return val\n");
}
MsiSetProperty(hpkg, "one", "one 1234"); MsiSetProperty(hpkg, "one", "one 1234");
MsiSetProperty(hpkg, "two", "1"); MsiSetProperty(hpkg, "two", "1");
...@@ -1056,10 +1053,7 @@ static void test_condition(void) ...@@ -1056,10 +1053,7 @@ static void test_condition(void)
MsiSetProperty(hpkg, "one", "hithere"); MsiSetProperty(hpkg, "one", "hithere");
MsiSetProperty(hpkg, "two", "hi"); MsiSetProperty(hpkg, "two", "hi");
r = MsiEvaluateCondition(hpkg, "one << two"); r = MsiEvaluateCondition(hpkg, "one << two");
todo_wine ok( r == MSICONDITION_TRUE, "wrong return val\n");
{
ok( r == MSICONDITION_TRUE, "wrong return val\n");
}
MsiSetProperty(hpkg, "one", "hi"); MsiSetProperty(hpkg, "one", "hi");
MsiSetProperty(hpkg, "two", "hithere"); MsiSetProperty(hpkg, "two", "hithere");
...@@ -1069,10 +1063,7 @@ static void test_condition(void) ...@@ -1069,10 +1063,7 @@ static void test_condition(void)
MsiSetProperty(hpkg, "one", "hi"); MsiSetProperty(hpkg, "one", "hi");
MsiSetProperty(hpkg, "two", "hi"); MsiSetProperty(hpkg, "two", "hi");
r = MsiEvaluateCondition(hpkg, "one << two"); r = MsiEvaluateCondition(hpkg, "one << two");
todo_wine ok( r == MSICONDITION_TRUE, "wrong return val\n");
{
ok( r == MSICONDITION_TRUE, "wrong return val\n");
}
MsiSetProperty(hpkg, "one", "abcdhithere"); MsiSetProperty(hpkg, "one", "abcdhithere");
MsiSetProperty(hpkg, "two", "hi"); MsiSetProperty(hpkg, "two", "hi");
...@@ -1087,10 +1078,7 @@ static void test_condition(void) ...@@ -1087,10 +1078,7 @@ static void test_condition(void)
MsiSetProperty(hpkg, "one", "hithere"); MsiSetProperty(hpkg, "one", "hithere");
MsiSetProperty(hpkg, "two", ""); MsiSetProperty(hpkg, "two", "");
r = MsiEvaluateCondition(hpkg, "one << two"); r = MsiEvaluateCondition(hpkg, "one << two");
todo_wine ok( r == MSICONDITION_TRUE, "wrong return val\n");
{
ok( r == MSICONDITION_TRUE, "wrong return val\n");
}
MsiSetProperty(hpkg, "one", ""); MsiSetProperty(hpkg, "one", "");
MsiSetProperty(hpkg, "two", ""); MsiSetProperty(hpkg, "two", "");
...@@ -1105,90 +1093,57 @@ static void test_condition(void) ...@@ -1105,90 +1093,57 @@ static void test_condition(void)
MsiSetProperty(hpkg, "one", "1234 one"); MsiSetProperty(hpkg, "one", "1234 one");
MsiSetProperty(hpkg, "two", "1"); MsiSetProperty(hpkg, "two", "1");
r = MsiEvaluateCondition(hpkg, "one << two"); r = MsiEvaluateCondition(hpkg, "one << two");
todo_wine ok( r == MSICONDITION_TRUE, "wrong return val\n");
{
ok( r == MSICONDITION_TRUE, "wrong return val\n");
}
MsiSetProperty(hpkg, "one", "hithere"); MsiSetProperty(hpkg, "one", "hithere");
MsiSetProperty(hpkg, "two", "there"); MsiSetProperty(hpkg, "two", "there");
r = MsiEvaluateCondition(hpkg, "one >> two"); r = MsiEvaluateCondition(hpkg, "one >> two");
todo_wine ok( r == MSICONDITION_TRUE, "wrong return val\n");
{
ok( r == MSICONDITION_TRUE, "wrong return val\n");
}
MsiSetProperty(hpkg, "one", "hithere"); MsiSetProperty(hpkg, "one", "hithere");
MsiSetProperty(hpkg, "two", "hi"); MsiSetProperty(hpkg, "two", "hi");
r = MsiEvaluateCondition(hpkg, "one >> two"); r = MsiEvaluateCondition(hpkg, "one >> two");
todo_wine ok( r == MSICONDITION_FALSE, "wrong return val\n");
{
ok( r == MSICONDITION_FALSE, "wrong return val\n");
}
MsiSetProperty(hpkg, "one", "there"); MsiSetProperty(hpkg, "one", "there");
MsiSetProperty(hpkg, "two", "hithere"); MsiSetProperty(hpkg, "two", "hithere");
r = MsiEvaluateCondition(hpkg, "one >> two"); r = MsiEvaluateCondition(hpkg, "one >> two");
todo_wine ok( r == MSICONDITION_FALSE, "wrong return val\n");
{
ok( r == MSICONDITION_FALSE, "wrong return val\n");
}
MsiSetProperty(hpkg, "one", "there"); MsiSetProperty(hpkg, "one", "there");
MsiSetProperty(hpkg, "two", "there"); MsiSetProperty(hpkg, "two", "there");
r = MsiEvaluateCondition(hpkg, "one >> two"); r = MsiEvaluateCondition(hpkg, "one >> two");
todo_wine ok( r == MSICONDITION_TRUE, "wrong return val\n");
{
ok( r == MSICONDITION_TRUE, "wrong return val\n");
}
MsiSetProperty(hpkg, "one", "abcdhithere"); MsiSetProperty(hpkg, "one", "abcdhithere");
MsiSetProperty(hpkg, "two", "hi"); MsiSetProperty(hpkg, "two", "hi");
r = MsiEvaluateCondition(hpkg, "one >> two"); r = MsiEvaluateCondition(hpkg, "one >> two");
todo_wine ok( r == MSICONDITION_FALSE, "wrong return val\n");
{
ok( r == MSICONDITION_FALSE, "wrong return val\n");
}
MsiSetProperty(hpkg, "one", ""); MsiSetProperty(hpkg, "one", "");
MsiSetProperty(hpkg, "two", "there"); MsiSetProperty(hpkg, "two", "there");
r = MsiEvaluateCondition(hpkg, "one >> two"); r = MsiEvaluateCondition(hpkg, "one >> two");
todo_wine ok( r == MSICONDITION_FALSE, "wrong return val\n");
{
ok( r == MSICONDITION_FALSE, "wrong return val\n");
}
MsiSetProperty(hpkg, "one", "there"); MsiSetProperty(hpkg, "one", "there");
MsiSetProperty(hpkg, "two", ""); MsiSetProperty(hpkg, "two", "");
r = MsiEvaluateCondition(hpkg, "one >> two"); r = MsiEvaluateCondition(hpkg, "one >> two");
todo_wine ok( r == MSICONDITION_TRUE, "wrong return val\n");
{
ok( r == MSICONDITION_TRUE, "wrong return val\n");
}
MsiSetProperty(hpkg, "one", ""); MsiSetProperty(hpkg, "one", "");
MsiSetProperty(hpkg, "two", ""); MsiSetProperty(hpkg, "two", "");
r = MsiEvaluateCondition(hpkg, "one >> two"); r = MsiEvaluateCondition(hpkg, "one >> two");
todo_wine ok( r == MSICONDITION_FALSE, "wrong return val\n");
{
ok( r == MSICONDITION_FALSE, "wrong return val\n");
}
MsiSetProperty(hpkg, "one", "1234"); MsiSetProperty(hpkg, "one", "1234");
MsiSetProperty(hpkg, "two", "4"); MsiSetProperty(hpkg, "two", "4");
r = MsiEvaluateCondition(hpkg, "one >> two"); r = MsiEvaluateCondition(hpkg, "one >> two");
todo_wine ok( r == MSICONDITION_FALSE, "wrong return val\n");
{
ok( r == MSICONDITION_FALSE, "wrong return val\n");
}
MsiSetProperty(hpkg, "one", "one 1234"); MsiSetProperty(hpkg, "one", "one 1234");
MsiSetProperty(hpkg, "two", "4"); MsiSetProperty(hpkg, "two", "4");
r = MsiEvaluateCondition(hpkg, "one >> two"); r = MsiEvaluateCondition(hpkg, "one >> two");
todo_wine ok( r == MSICONDITION_TRUE, "wrong return val\n");
{
ok( r == MSICONDITION_TRUE, "wrong return val\n");
}
MsiCloseHandle( hpkg ); MsiCloseHandle( hpkg );
DeleteFile(msifile); DeleteFile(msifile);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment