Commit 86d8abdb authored by unknown's avatar unknown
Browse files

Make status of NO_BACKSLASH_ESCAPES mode known to the client so

it can use it to switch to only quoting apostrophes by doubling
them when it is in effect. (Bug #10214)


include/my_sys.h:
  Add new escape_quotes_for_mysql() function
include/mysql_com.h:
  Add SERVER_STATUS_NO_BACKSLASH_ESCAPES
libmysql/libmysql.c:
  Use SERVER_STATUS_NO_BACKSLASH_ESCAPES in server_status to determine
  how mysql_real_escape_string() should do quoting.
mysys/charset.c:
  Add new escape_quotes_for_mysql() function that only quotes
  apostrophes by doubling them up.
sql/set_var.cc:
  Set SERVER_STATUS_NO_BACKSLASH_ESCAPES when MODE_NO_BACKSLASH_ESCAPES
  changes.
sql/sql_class.cc:
  Set SERVER_STATUS_NO_BACKSLASH_ESCAPES when necessary on thread creation.
tests/mysql_client_test.c:
  Add new test for sending NO_BACKSLASH_ESCAPES as part of server_status.
parent d34e2ccb
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -865,6 +865,9 @@ extern void add_compiled_collation(CHARSET_INFO *cs);
extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
                                     char *to, ulong to_length,
                                     const char *from, ulong length);
extern ulong escape_quotes_for_mysql(CHARSET_INFO *charset_info,
                                     char *to, ulong to_length,
                                     const char *from, ulong length);

extern void thd_increment_bytes_sent(ulong length);
extern void thd_increment_bytes_received(ulong length);
+1 −0
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@ enum enum_server_command
*/
#define SERVER_STATUS_LAST_ROW_SENT 128
#define SERVER_STATUS_DB_DROPPED        256 /* A database was dropped */
#define SERVER_STATUS_NO_BACKSLASH_ESCAPES 512

#define MYSQL_ERRMSG_SIZE	512
#define NET_READ_TIMEOUT	30		/* Timeout on read */
+8 −1
Original line number Diff line number Diff line
@@ -1615,9 +1615,16 @@ mysql_escape_string(char *to,const char *from,ulong length)
ulong STDCALL
mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
			 ulong length)
{
  if (mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
  {
    return escape_quotes_for_mysql(mysql->charset, to, 0, from, length);
  }
  else
  {
    return escape_string_for_mysql(mysql->charset, to, 0, from, length);
  }
}


char * STDCALL
+64 −0
Original line number Diff line number Diff line
@@ -656,3 +656,67 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
  return overflow ? (ulong)~0 : (ulong) (to - to_start);
}


/*
  NOTE
    to be consistent with escape_string_for_mysql(), to_length may be 0 to
    mean "big enough"
  RETURN
    the length of the escaped string or ~0 if it did not fit.
*/
ulong escape_quotes_for_mysql(CHARSET_INFO *charset_info,
                              char *to, ulong to_length,
                              const char *from, ulong length)
{
  const char *to_start= to;
  const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
  my_bool overflow=0;
#ifdef USE_MB
  my_bool use_mb_flag= use_mb(charset_info);
#endif
  for (end= from + length; from < end; from++)
  {
    char escape=0;
#ifdef USE_MB
    int tmp_length;
    if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
    {
      if (to + tmp_length > to_end)
      {
        overflow=1;
        break;
      }
      while (tmp_length--)
	*to++= *from++;
      from--;
      continue;
    }
    /*
      We don't have the same issue here with a non-multi-byte character being
      turned into a multi-byte character by the addition of an escaping
      character, because we are only escaping the ' character with itself.
     */
#endif
    if (*from == '\'')
    {
      if (to + 2 > to_end)
      {
        overflow=1;
        break;
      }
      *to++= '\'';
      *to++= '\'';
    }
    else
    {
      if (to + 1 > to_end)
      {
        overflow=1;
        break;
      }
      *to++= *from;
    }
  }
  *to= 0;
  return overflow ? (ulong)~0 : (ulong) (to - to_start);
}
+9 −0
Original line number Diff line number Diff line
@@ -3238,7 +3238,16 @@ void fix_sql_mode_var(THD *thd, enum_var_type type)
    global_system_variables.sql_mode=
      fix_sql_mode(global_system_variables.sql_mode);
  else
  {
    thd->variables.sql_mode= fix_sql_mode(thd->variables.sql_mode);
    /*
      Update thd->server_status
     */
    if (thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
      thd->server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
    else
      thd->server_status&= ~SERVER_STATUS_NO_BACKSLASH_ESCAPES;
  }
}

/* Map database specific bits to function bits */
Loading