jparanich
jparanich

Reputation: 8994

Efficiently escaping quotes in C before passing to mysql_query

In a nutshell I typically build a MySQL query within C using sprintf

i.e.

sprintf(sqlcmd,"update foo set dog=\"lab\" where description=\"%s\"",some_desc);
mysql_query(some_conn,sqlcmd);

However if some_desc is something like Crazy 5" Dog, then MySql Server screams, as it's confused over the dangling quote.

Is it best, within C, to scan some_desc replacing " with "", OR is there a function in MySql to wrap this better... i.e. description=string(Crazy 5" Dog) ?

Thanks!

Upvotes: 2

Views: 3041

Answers (3)

Francisco Soto
Francisco Soto

Reputation: 10392

MySQL does that already for you

http://dev.mysql.com/doc/refman/5.0/en/mysql-real-escape-string.html

Upvotes: 3

ninjalj
ninjalj

Reputation: 43688

Although MySQL has a mysql_real_escape_string() function, you should probably be using prepared statements instead, which allow you to use ? placeholders instead of real parameters, and then bind them to the real parameters before each execution of the statement.

Upvotes: 7

David M. Syzdek
David M. Syzdek

Reputation: 15788

I would write a simple escape function like the following:

size_t escape_mysql_string(const char * input, size_t input_size,
   char * output, size_t output_size)
{
   unsigned long ipos; // position within input buffer
   unsigned long opos; // position within output buffer

   // quick check to verify output buffer is at least as large as input buffer
   if (output_size < (input_size+2))
      return(0);

   // loop through input buffer
   opos = 0;
   for(ipos = 0; ((ipos < input_size) && (input[ipos])); ipos++)
   {
      // verify that output buffer has room for escaped input
      if ((opos+2) >= output_size)
      {
         output[opos] = '\0';
         return(opos);
      };

      switch(input[ipos])
      {
         // escape ("""), ("'"), ("\"), ("%"), and ("_") characters
         case '\'':
         case '\"':
         case '\\':
         case '%':
         case '_':
         output[opos] = '\\';
         opos++;
         output[opos] = input[ipos];
         break;

         // escape newlines
         case '\n':
         output[opos] = '\\';
         opos++;
         output[opos] = 'n';
         break;

         // escape carriage returns
         case '\r':
         output[opos] = '\\';
         opos++;
         output[opos] = 'r';
         break;

         // escape tabs
         case '\t':
         output[opos] = '\\';
         opos++;
         output[opos] = 't';
         break;

         // save unescapd input character
         default:
         output[opos] = input[ipos];
         break;
      };
      opos++;
   };

   output[opos] ='\0';
   return(opos);
}

The call it with something like the following:

char some_escaped_desc[1024];
escape_mysql_string(some_desc, strlen(some_desc), some_escaped_desc, 1024);

Upvotes: -2

Related Questions