List:Commits« Previous MessageNext Message »
From:jbalint Date:March 11 2008 1:59pm
Subject:Connector/ODBC 3.51 commit: r1057 - in trunk: . driver test
View as plain text  
Modified:
   trunk/ChangeLog
   trunk/driver/catalog.c
   trunk/driver/myutil.h
   trunk/driver/utility.c
   trunk/test/my_catalog.c
Log:
MyODBC Crystal Reports can't connect to a tbl if a field name has a single quote (Bug
#32989)

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2008-03-11 13:17:54 UTC (rev 1056)
+++ trunk/ChangeLog	2008-03-11 13:59:45 UTC (rev 1057)
@@ -23,6 +23,8 @@
   * An SQLSTATE of HY000 was returned when a stored procedure was not found,
     instead of 42000. This caused problems with ADO's adCmdUnknown option.
     (Bug #27158)
+  * MyODBC Crystal Reports can't connect to a tbl if a field name has a
+    single quote. (Bug #32989)
 
 ----
 

Modified: trunk/driver/catalog.c
===================================================================
--- trunk/driver/catalog.c	2008-03-11 13:17:54 UTC (rev 1056)
+++ trunk/driver/catalog.c	2008-03-11 13:59:45 UTC (rev 1057)
@@ -280,7 +280,8 @@
   if (catalog && *catalog)
   {
     to= strmov(to, "FROM `");
-    to+= mysql_real_escape_string(mysql, to, (char *)catalog, catalog_length);
+    to+= myodbc_escape_string(mysql, to, sizeof(buff) - (to - buff),
+                              (char *)catalog, catalog_length, 1);
     to= strmov(to, "` ");
   }
 
@@ -298,8 +299,8 @@
     if (wildcard)
       to+= mysql_real_escape_string(mysql, to, (char *)table, table_length);
     else
-      to+= myodbc_escape_wildcard(mysql, to, sizeof(buff) - (to - buff),
-                                  (char *)table, table_length);
+      to+= myodbc_escape_string(mysql, to, sizeof(buff) - (to - buff),
+                                (char *)table, table_length, 0);
     to= strmov(to, "'");
   }
 
@@ -611,17 +612,20 @@
   {
     char buff[255];
     char *select, *to;
+    size_t select_len;
     unsigned long *lengths;
 
     /* Get a list of column names that match our criteria. */
     to= strmov(buff, "SHOW COLUMNS FROM `");
     if (cbCatalog)
     {
-      to+= mysql_real_escape_string(mysql, to, (char *)szCatalog, cbCatalog);
+      to+= myodbc_escape_string(mysql, to, sizeof(buff) - (to - buff),
+                                (char *)szCatalog, cbCatalog, 1);
       to= strmov(to, "`.`");
     }
 
-    to+= mysql_real_escape_string(mysql, to, (char *)szTable, cbTable);
+    to+= myodbc_escape_string(mysql, to, sizeof(buff) - (to - buff),
+                              (char *)szTable, cbTable, 1);
     to= strmov(to, "`");
 
     if (cbColumn)
@@ -643,9 +647,8 @@
     pthread_mutex_unlock(&dbc->lock);
 
     /* Build a SELECT ... LIMIT 0 to get the field metadata. */
-    if (!(select= (char *)my_malloc(sizeof(char) * (ulong)result->row_count *
-                                    (NAME_LEN + 1) + NAME_LEN * 2,
-                                    MYF(0))))
+    select_len = (ulong)result->row_count * (NAME_LEN + 1) + NAME_LEN * 2;
+    if (!(select= (char *)my_malloc(select_len, MYF(0))))
     {
       set_mem_error(mysql);
       return NULL;
@@ -656,7 +659,8 @@
     {
       to= strmov(to, "`");
       lengths= mysql_fetch_lengths(result);
-      to+= mysql_real_escape_string(mysql, to, row[0], lengths[0]);
+      to+= myodbc_escape_string(mysql, to, select_len - (to - select),
+                                (char *)row[0], lengths[0], 1);
       to= strmov(to, "`,");
     }
     *(--to)= '\0';
@@ -664,11 +668,13 @@
     to= strmov(to, " FROM `");
     if (cbCatalog)
     {
-      to+= mysql_real_escape_string(mysql, to, (char *)szCatalog, cbCatalog);
+      to+= myodbc_escape_string(mysql, to, select_len - (to - select),
+                                (char *)szCatalog, cbCatalog, 1);
       to= strmov(to, "`.`");
     }
 
-    to+= mysql_real_escape_string(mysql, to, (char *)szTable, cbTable);
+    to+= myodbc_escape_string(mysql, to, select_len - (to - select),
+                              (char *)szTable, cbTable, 1);
     to= strmov(to, "` LIMIT 0");
 
     mysql_free_result(result);

Modified: trunk/driver/myutil.h
===================================================================
--- trunk/driver/myutil.h	2008-03-11 13:17:54 UTC (rev 1056)
+++ trunk/driver/myutil.h	2008-03-11 13:59:45 UTC (rev 1057)
@@ -216,8 +216,8 @@
 int myodbc_casecmp(const char *s, const char *t, uint len);
 my_bool reget_current_catalog(DBC FAR *dbc);
 
-ulong myodbc_escape_wildcard(MYSQL *mysql, char *to, ulong to_length,
-                             const char *from, ulong length);
+ulong myodbc_escape_string(MYSQL *mysql, char *to, ulong to_length,
+                           const char *from, ulong length, int escape_id);
 
 /* Functions used when debugging */
 void query_print(FILE *log_file,char *query);

Modified: trunk/driver/utility.c
===================================================================
--- trunk/driver/utility.c	2008-03-11 13:17:54 UTC (rev 1056)
+++ trunk/driver/utility.c	2008-03-11 13:59:45 UTC (rev 1057)
@@ -1428,18 +1428,19 @@
 /**
  Escapes a string that may contain wildcard characters (%, _) and other
  problematic characters (", ', \n, etc). Like mysql_real_escape_string() but
- also including % and _.
+ also including % and _. Can be used with an identified by passing escape_id.
 
  @param[in]   mysql         Pointer to MYSQL structure
  @param[out]  to            Buffer for escaped string
  @param[in]   to_length     Length of destination buffer, or 0 for "big enough"
  @param[in]   from          The string to escape
  @param[in]   length        The length of the string to escape
+ @param[in]   escape_id     Escaping an identified that will be quoted
 
 */
-ulong myodbc_escape_wildcard(MYSQL *mysql __attribute__((unused)),
-                             char *to, ulong to_length,
-                             const char *from, ulong length)
+ulong myodbc_escape_string(MYSQL *mysql __attribute__((unused)),
+                           char *to, ulong to_length,
+                           const char *from, ulong length, int escape_id)
 {
   const char *to_start= to;
   const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
@@ -1461,7 +1462,7 @@
         break;
       }
       while (tmp_length--)
-	*to++= *from++;
+        *to++= *from++;
       from--;
       continue;
     }
@@ -1481,34 +1482,34 @@
     else
 #endif
     switch (*from) {
-    case 0:				/* Must be escaped for 'mysql' */
+    case 0:         /* Must be escaped for 'mysql' */
       escape= '0';
       break;
-    case '\n':				/* Must be escaped for logs */
+    case '\n':      /* Must be escaped for logs */
       escape= 'n';
       break;
     case '\r':
       escape= 'r';
       break;
     case '\\':
-      escape= '\\';
-      break;
     case '\'':
-      escape= '\'';
-      break;
-    case '"':				/* Better safe than sorry */
-      escape= '"';
-      break;
+    case '"':       /* Better safe than sorry */
     case '_':
-      escape= '_';
-      break;
     case '%':
-      escape= '%';
+      escape= *from;
       break;
-    case '\032':			/* This gives problems on Win32 */
+    case '\032':    /* This gives problems on Win32 */
       escape= 'Z';
       break;
     }
+    /* if escaping an id, only handle back-tick */
+    if (escape_id)
+    {
+      if (*from == '`')
+        escape= *from;
+      else
+        escape= 0;
+    }
     if (escape)
     {
       if (to + 2 > to_end)

Modified: trunk/test/my_catalog.c
===================================================================
--- trunk/test/my_catalog.c	2008-03-11 13:17:54 UTC (rev 1056)
+++ trunk/test/my_catalog.c	2008-03-11 13:59:45 UTC (rev 1057)
@@ -1153,6 +1153,31 @@
 }
 
 
+/*
+  Bug #32989 - Crystal Reports fails if a field has a single quote
+*/
+DECLARE_TEST(t_bug32989)
+{
+  SQLCHAR name[20];
+  SQLLEN len;
+
+  ok_sql(hstmt, "drop table if exists t_bug32989");
+  ok_sql(hstmt, "create table t_bug32989 (`doesn't work` int)");
+
+  ok_stmt(hstmt, SQLColumns(hstmt, "test", SQL_NTS, NULL, 0,
+                            "t_bug32989", SQL_NTS, NULL, 0));
+  ok_stmt(hstmt, SQLFetch(hstmt));
+
+  ok_stmt(hstmt, SQLGetData(hstmt, 4, SQL_C_CHAR, name, 20, &len));
+  is_num(len, 12);
+  is_str(name, "doesn't work", 13);
+  ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE));
+
+  ok_sql(hstmt, "drop table if exists t_bug32989");
+  return OK;
+}
+
+
 BEGIN_TESTS
   ADD_TEST(my_columns_null)
   ADD_TEST(my_drop_table)
@@ -1176,6 +1201,7 @@
   ADD_TEST(t_bug29888)
   ADD_TEST(t_bug14407)
   ADD_TEST(t_bug32864)
+  ADD_TEST(t_bug32989)
 END_TESTS
 
 

Thread
Connector/ODBC 3.51 commit: r1057 - in trunk: . driver testjbalint11 Mar