Re: [CODE] calling char function from sprintf

From: Daniel A. Koepke (dkoepke@circlemud.org)
Date: 09/05/01


On Wed, 5 Sep 2001, Artovil wrote:

> Don't I have to add the quotes like that since I am processing the
> strings with mysql_real_escape_string()?  Or am I entirely missing
> something?

You can do the following instead:

  /* arg1 == "George" */
  /* arg2 == "George's the best!" */
  mysql_real_escape_string(sql, quo1, arg1, strlen(arg1));
  mysql_real_escape_string(sql, quo2, arg2, strlen(arg2));

  sprintf(que,
          "INSERT INTO player_index (Name, Title) VALUES('%s', '%s')",
          quo1, quo2);

But, yes, you need to take care to only escape the strings you want to
escape (sorry if that sounds fairly obvious, but that's what it boils down
to).  I earlier made a mistake in assuming you could wrap the call with a
function that returns a static, but the calls back-to-back clobber each
other (that'll teach me to write posts at 3:30am), so here's another way:

  char *escape(MYSQL *mysql, const char *str)
  {
    static char sql_buffer[MAX_STRING_LENGTH*4+1];
    const char *top = sql_buffer + (MAX_STRING_LENGTH * 4);
    static char *ptr = sql_buffer;
    static char *rvl;

    if (ptr + strlen(str) > top)
      ptr = sql_buffer;

    rvl = ptr;
    ptr += mysql_real_escape_string(mysql, rvl, str, strlen(str)) + 1;
    return (rvl);
  }

The trick here is that we have a single large buffer that we use parts of
in back-to-back calls, so we don't clobber the information that's already
there.  In the function, sql_buffer[] is the actual buffer we're writing
to; ptr is our location in the buffer; and rvl is a pointer to the
beginning of the substring we're returning.  If we reach the top of the
sql_buffer[], we loop back to its beginning.  This means that if you write
a whole ton of escaped data (32k as it stands), you'll start looping over
and clobbering it.  In which case, you need to make sql_buffer[] larger
(and ensure that top continues to point to the top of it -- just change
the multiple from 4 to something else).

Now we can finally write

  sprintf(buf, "INSERT INTO player_idx (Name, Title) VALUES('%s', '%s')",
          escape(sql, "George"), escape(sql, "George's the Best"));

or, since I suspect your MYSQL pointer is global (otherwise, you'd have to
change a lot of functions to receive the handle, just in case you wanted
to run a query there), you can change the escape() function to remove the
first argument and work directly with the global.


-dak

--
   +---------------------------------------------------------------+
   | FAQ: http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html |
   | Archives: http://post.queensu.ca/listserv/wwwarch/circle.html |
   +---------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/06/01 PST