[1/2] msi: Accept a missing left backquote in SQL identifiers.

Hans Leidekker hans at codeweavers.com
Tue Jan 3 06:53:14 CST 2012


Fixes http://bugs.winehq.org/show_bug.cgi?id=29328
---
 dlls/msi/query.h    |    2 +-
 dlls/msi/sql.y      |    5 +++--
 dlls/msi/tests/db.c |   30 ++++++++++++++++++++++++++++++
 dlls/msi/tokenize.c |    5 ++++-
 4 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/dlls/msi/query.h b/dlls/msi/query.h
index 8f8a244..ca34b4c 100644
--- a/dlls/msi/query.h
+++ b/dlls/msi/query.h
@@ -131,7 +131,7 @@ UINT STORAGES_CreateView( MSIDATABASE *db, MSIVIEW **view ) DECLSPEC_HIDDEN;
 
 UINT DROP_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR name ) DECLSPEC_HIDDEN;
 
-int sqliteGetToken(const WCHAR *z, int *tokenType) DECLSPEC_HIDDEN;
+int sqliteGetToken(const WCHAR *z, int *tokenType, int *skip) DECLSPEC_HIDDEN;
 
 MSIRECORD *msi_query_merge_record( UINT fields, const column_info *vl, MSIRECORD *rec ) DECLSPEC_HIDDEN;
 
diff --git a/dlls/msi/sql.y b/dlls/msi/sql.y
index 548e142..ead7743 100644
--- a/dlls/msi/sql.y
+++ b/dlls/msi/sql.y
@@ -797,7 +797,7 @@ static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR colu
 
 static int sql_lex( void *SQL_lval, SQL_input *sql )
 {
-    int token;
+    int token, skip;
     struct sql_str * str = SQL_lval;
 
     do
@@ -807,11 +807,12 @@ static int sql_lex( void *SQL_lval, SQL_input *sql )
             return 0;  /* end of input */
 
         /* TRACE("string : %s\n", debugstr_w(&sql->command[sql->n])); */
-        sql->len = sqliteGetToken( &sql->command[sql->n], &token );
+        sql->len = sqliteGetToken( &sql->command[sql->n], &token, &skip );
         if( sql->len==0 )
             break;
         str->data = &sql->command[sql->n];
         str->len = sql->len;
+        sql->n += skip;
     }
     while( token == TK_SPACE );
 
diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c
index 6ecd642..d33eb0c 100644
--- a/dlls/msi/tests/db.c
+++ b/dlls/msi/tests/db.c
@@ -727,6 +727,36 @@ static void test_msibadqueries(void)
     r = try_query( hdb, "select * from 'c'");
     ok(r == ERROR_BAD_QUERY_SYNTAX, "query failed\n");
 
+    r = try_query( hdb, "select `c`.`b` from `c` order by `c`.`order`");
+    ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
+
+    r = try_query( hdb, "select `c`.b` from `c`");
+    ok( r == ERROR_SUCCESS, "query failed: %u\n", r );
+
+    r = try_query( hdb, "select `c`.`b from `c`");
+    ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
+
+    r = try_query( hdb, "select `c`.b from `c`");
+    ok( r == ERROR_SUCCESS, "query failed: %u\n", r );
+
+    r = try_query( hdb, "select `c.`b` from `c`");
+    ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
+
+    r = try_query( hdb, "select c`.`b` from `c`");
+    ok( r == ERROR_SUCCESS, "query failed: %u\n", r );
+
+    r = try_query( hdb, "select c.`b` from `c`");
+    ok( r == ERROR_SUCCESS, "query failed: %u\n", r );
+
+    r = try_query( hdb, "select `c`.`b` from c`");
+    ok( r == ERROR_SUCCESS, "query failed: %u\n", r );
+
+    r = try_query( hdb, "select `c`.`b` from `c");
+    ok( r == ERROR_BAD_QUERY_SYNTAX, "query failed: %u\n", r );
+
+    r = try_query( hdb, "select `c`.`b` from c");
+    ok( r == ERROR_SUCCESS, "query failed: %u\n", r );
+
     r = try_query( hdb, "CREATE TABLE `\5a` (`b` CHAR NOT NULL PRIMARY KEY `b`)" );
     ok( r == ERROR_SUCCESS , "query failed: %u\n", r );
 
diff --git a/dlls/msi/tokenize.c b/dlls/msi/tokenize.c
index 64e14b8..c432888 100644
--- a/dlls/msi/tokenize.c
+++ b/dlls/msi/tokenize.c
@@ -190,8 +190,10 @@ static const char isIdChar[] = {
 ** -1 if the token is (or might be) incomplete.  Store the token
 ** type in *tokenType before returning.
 */
-int sqliteGetToken(const WCHAR *z, int *tokenType){
+int sqliteGetToken(const WCHAR *z, int *tokenType, int *skip){
   int i;
+
+  *skip = 0;
   switch( *z ){
     case ' ': case '\t': case '\n': case '\f':
       for(i=1; isspace(z[i]) && z[i] != '\r'; i++){}
@@ -280,6 +282,7 @@ int sqliteGetToken(const WCHAR *z, int *tokenType){
       }
       for(i=1; isIdChar[z[i]]; i++){}
       *tokenType = sqliteKeywordCode(z, i);
+      if( *tokenType == TK_ID && z[i] == '`' ) *skip = 1;
       return i;
   }
   *tokenType = TK_ILLEGAL;
-- 
1.7.7.3







More information about the wine-patches mailing list