From 6a042307a56270e1bd5fe6ad6a53d6cc68942d57 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Tue, 28 Jan 2014 13:26:16 +0100 Subject: [PATCH] wbemprox: Allow string values in boolean comparisons. --- dlls/wbemprox/builtin.c | 4 +- dlls/wbemprox/query.c | 113 +++++++++++++++++++++++++++++++++++---- dlls/wbemprox/wbemprox_private.h | 2 +- 3 files changed, 107 insertions(+), 12 deletions(-) diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index 58054de5e71..3086a4fefd0 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -806,12 +806,14 @@ static const struct record_stdregprov data_stdregprov[] = static BOOL match_row( const struct table *table, UINT row, const struct expr *cond, enum fill_status *status ) { LONGLONG val; + UINT type; + if (!cond) { *status = FILL_STATUS_UNFILTERED; return TRUE; } - if (eval_cond( table, row, cond, &val ) != S_OK) + if (eval_cond( table, row, cond, &val, &type ) != S_OK) { *status = FILL_STATUS_FAILED; return FALSE; diff --git a/dlls/wbemprox/query.c b/dlls/wbemprox/query.c index 5134d5bcd68..bd68560a6f9 100644 --- a/dlls/wbemprox/query.c +++ b/dlls/wbemprox/query.c @@ -114,16 +114,93 @@ static inline BOOL is_strcmp( const struct complex_expr *expr ) (expr->left->type == EXPR_SVAL && expr->right->type == EXPR_PROPVAL)); } +static inline BOOL is_boolcmp( const struct complex_expr *expr, UINT ltype, UINT rtype ) +{ + if (ltype == CIM_BOOLEAN && expr->left->type == EXPR_PROPVAL && + (expr->right->type == EXPR_SVAL || expr->right->type == EXPR_BVAL)) return TRUE; + else if (rtype == CIM_BOOLEAN && expr->right->type == EXPR_PROPVAL && + (expr->left->type == EXPR_SVAL || expr->left->type == EXPR_BVAL)) return TRUE; + return FALSE; +} + +static HRESULT eval_boolcmp( UINT op, LONGLONG lval, LONGLONG rval, UINT ltype, UINT rtype, LONGLONG *val ) +{ + static const WCHAR trueW[] = {'T','r','u','e',0}; + + if (ltype == CIM_STRING) lval = !strcmpiW( (const WCHAR *)(INT_PTR)lval, trueW ) ? -1 : 0; + else if (rtype == CIM_STRING) rval = !strcmpiW( (const WCHAR *)(INT_PTR)rval, trueW ) ? -1 : 0; + + switch (op) + { + case OP_EQ: + *val = (lval == rval); + break; + case OP_NE: + *val = (lval != rval); + break; + default: + ERR("unhandled operator %u\n", op); + return WBEM_E_INVALID_QUERY; + } + return S_OK; +} + +static UINT resolve_type( UINT left, UINT right ) +{ + switch (left) + { + case CIM_SINT8: + case CIM_SINT16: + case CIM_SINT32: + case CIM_SINT64: + case CIM_UINT8: + case CIM_UINT16: + case CIM_UINT32: + case CIM_UINT64: + switch (right) + { + case CIM_SINT8: + case CIM_SINT16: + case CIM_SINT32: + case CIM_SINT64: + case CIM_UINT8: + case CIM_UINT16: + case CIM_UINT32: + case CIM_UINT64: + return CIM_UINT64; + default: break; + } + + case CIM_STRING: + if (right == CIM_STRING) return CIM_STRING; + break; + + case CIM_BOOLEAN: + if (right == CIM_BOOLEAN) return CIM_BOOLEAN; + break; + + default: + break; + } + return CIM_ILLEGAL; +} + static HRESULT eval_binary( const struct table *table, UINT row, const struct complex_expr *expr, - LONGLONG *val ) + LONGLONG *val, UINT *type ) { HRESULT lret, rret; LONGLONG lval, rval; + UINT ltype, rtype; - lret = eval_cond( table, row, expr->left, &lval ); - rret = eval_cond( table, row, expr->right, &rval ); + lret = eval_cond( table, row, expr->left, &lval, <ype ); + rret = eval_cond( table, row, expr->right, &rval, &rtype ); if (lret != S_OK || rret != S_OK) return WBEM_E_INVALID_QUERY; + *type = resolve_type( ltype, rtype ); + + if (is_boolcmp( expr, ltype, rtype )) + return eval_boolcmp( expr->op, lval, rval, ltype, rtype, val ); + if (is_strcmp( expr )) { const WCHAR *lstr = (const WCHAR *)(INT_PTR)lval; @@ -165,7 +242,7 @@ static HRESULT eval_binary( const struct table *table, UINT row, const struct co } static HRESULT eval_unary( const struct table *table, UINT row, const struct complex_expr *expr, - LONGLONG *val ) + LONGLONG *val, UINT *type ) { HRESULT hr; @@ -192,11 +269,13 @@ static HRESULT eval_unary( const struct table *table, UINT row, const struct com ERR("unknown operator %u\n", expr->op); return WBEM_E_INVALID_QUERY; } + + *type = table->columns[column].type & CIM_TYPE_MASK; return S_OK; } static HRESULT eval_propval( const struct table *table, UINT row, const struct property *propval, - LONGLONG *val ) + LONGLONG *val, UINT *type ) { HRESULT hr; @@ -206,31 +285,44 @@ static HRESULT eval_propval( const struct table *table, UINT row, const struct p if (hr != S_OK) return hr; + *type = table->columns[column].type & CIM_TYPE_MASK; return get_value( table, row, column, val ); } -HRESULT eval_cond( const struct table *table, UINT row, const struct expr *cond, LONGLONG *val ) +HRESULT eval_cond( const struct table *table, UINT row, const struct expr *cond, LONGLONG *val, UINT *type ) { if (!cond) { *val = 1; + *type = CIM_UINT64; return S_OK; } switch (cond->type) { case EXPR_COMPLEX: - return eval_binary( table, row, &cond->u.expr, val ); + return eval_binary( table, row, &cond->u.expr, val, type ); + case EXPR_UNARY: - return eval_unary( table, row, &cond->u.expr, val ); + return eval_unary( table, row, &cond->u.expr, val, type ); + case EXPR_PROPVAL: - return eval_propval( table, row, cond->u.propval, val ); + return eval_propval( table, row, cond->u.propval, val, type ); + case EXPR_SVAL: *val = (INT_PTR)cond->u.sval; + *type = CIM_STRING; return S_OK; + case EXPR_IVAL: + *val = cond->u.ival; + *type = CIM_UINT64; + return S_OK; + case EXPR_BVAL: *val = cond->u.ival; + *type = CIM_BOOLEAN; return S_OK; + default: ERR("invalid expression type\n"); break; @@ -257,6 +349,7 @@ HRESULT execute_view( struct view *view ) { HRESULT hr; LONGLONG val = 0; + UINT type; if (j >= len) { @@ -265,7 +358,7 @@ HRESULT execute_view( struct view *view ) if (!(tmp = heap_realloc( view->result, len * sizeof(UINT) ))) return E_OUTOFMEMORY; view->result = tmp; } - if ((hr = eval_cond( view->table, i, view->cond, &val )) != S_OK) return hr; + if ((hr = eval_cond( view->table, i, view->cond, &val, &type )) != S_OK) return hr; if (val) view->result[j++] = i; } view->count = j; diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h index 81c0fccbf42..0e39d00c22b 100644 --- a/dlls/wbemprox/wbemprox_private.h +++ b/dlls/wbemprox/wbemprox_private.h @@ -186,7 +186,7 @@ void free_row_values( const struct table *, UINT ) DECLSPEC_HIDDEN; void clear_table( struct table * ) DECLSPEC_HIDDEN; void free_table( struct table * ) DECLSPEC_HIDDEN; UINT get_type_size( CIMTYPE ) DECLSPEC_HIDDEN; -HRESULT eval_cond( const struct table *, UINT, const struct expr *, LONGLONG * ) DECLSPEC_HIDDEN; +HRESULT eval_cond( const struct table *, UINT, const struct expr *, LONGLONG *, UINT * ) DECLSPEC_HIDDEN; HRESULT get_column_index( const struct table *, const WCHAR *, UINT * ) DECLSPEC_HIDDEN; HRESULT get_value( const struct table *, UINT, UINT, LONGLONG * ) DECLSPEC_HIDDEN; BSTR get_value_bstr( const struct table *, UINT, UINT ) DECLSPEC_HIDDEN; -- 2.11.4.GIT