"Fossies" - the Fresh Open Source Software Archive

Member "mariadb-connector-c-3.0.9-src/unittest/libmariadb/charset.c" (8 Feb 2019, 26016 Bytes) of package /linux/misc/mariadb-connector-c-3.0.9-src.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "charset.c": 3.0.3-src_vs_3.0.4-src.

    1 /*
    2 Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    3 
    4 The MySQL Connector/C is licensed under the terms of the GPLv2
    5 <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
    6 MySQL Connectors. There are special exceptions to the terms and
    7 conditions of the GPLv2 as it is applied to this software, see the
    8 FLOSS License Exception
    9 <http://www.mysql.com/about/legal/licensing/foss-exception.html>.
   10 
   11 This program is free software; you can redistribute it and/or modify
   12 it under the terms of the GNU General Public License as published
   13 by the Free Software Foundation; version 2 of the License.
   14 
   15 This program is distributed in the hope that it will be useful, but
   16 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   17 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
   18 for more details.
   19 
   20 You should have received a copy of the GNU General Public License along
   21 with this program; if not, write to the Free Software Foundation, Inc.,
   22 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
   23 */
   24 
   25 #include "my_test.h"
   26 
   27 /*
   28  test gbk charset escaping
   29 
   30  The important part is that 0x27 (') is the second-byte in a invalid
   31  two-byte GBK character here. But 0xbf5c is a valid GBK character, so
   32  it needs to be escaped as 0x5cbf27
   33 
   34 */
   35 #define TEST_BUG8378_IN  "\xef\xbb\xbf\x27\xbf\x10"
   36 #define TEST_BUG8378_OUT "\xef\xbb\x5c\xbf\x5c\x27\x5c\xbf\x10"
   37 
   38 /* set connection options */
   39 struct my_option_st opt_bug8378[] = {
   40   {MYSQL_SET_CHARSET_NAME, (char *) "gbk"},
   41   {0, NULL}
   42 };
   43 
   44 int bug_8378(MYSQL *mysql) {
   45   int rc, len;
   46   char out[9], buf[256];
   47   MYSQL_RES *res;
   48   MYSQL_ROW row;
   49 
   50   len= mysql_real_escape_string(mysql, out, TEST_BUG8378_IN, 4);
   51   FAIL_IF(memcmp(out, TEST_BUG8378_OUT, len), "wrong result");
   52 
   53   sprintf(buf, "SELECT '%s' FROM DUAL", TEST_BUG8378_OUT);
   54  
   55   rc= mysql_query(mysql, buf);
   56   check_mysql_rc(rc, mysql);
   57 
   58   if ((res= mysql_store_result(mysql))) {
   59     row= mysql_fetch_row(res);
   60     if (memcmp(row[0], TEST_BUG8378_IN, 4)) {
   61       mysql_free_result(res);
   62       return FAIL;
   63     }
   64     mysql_free_result(res);
   65   } else
   66     return FAIL;
   67 
   68   return OK;
   69 }
   70 
   71 int test_client_character_set(MYSQL *mysql)
   72 {
   73   MY_CHARSET_INFO cs;
   74   char *csname= (char*) "utf8";
   75   char *csdefault= (char*)mysql_character_set_name(mysql);
   76 
   77   FAIL_IF(mysql_set_character_set(mysql, csname), mysql_error(mysql));
   78 
   79   mysql_get_character_set_info(mysql, &cs);
   80 
   81   FAIL_IF(strcmp(cs.csname, "utf8") || strcmp(cs.name, "utf8_general_ci"), "Character set != UTF8");
   82   FAIL_IF(mysql_set_character_set(mysql, csdefault), mysql_error(mysql));
   83 
   84   return OK;
   85 }
   86 
   87 /*
   88  * Regression test for bug #10214
   89  *
   90  * Test escaping with NO_BACKSLASH_ESCAPES
   91  *
   92  */
   93 int bug_10214(MYSQL *mysql)
   94 {
   95   int   len, rc;
   96   char  out[8];
   97 
   98   /* reset sql_mode */
   99   rc= mysql_query(mysql, "SET sql_mode=''");
  100   check_mysql_rc(rc, mysql);
  101 
  102   len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
  103   FAIL_IF(memcmp(out, "a\\'b\\\\c", len), NULL);
  104 
  105   rc= mysql_query(mysql, "set sql_mode='NO_BACKSLASH_ESCAPES'");
  106   check_mysql_rc(rc, mysql);
  107   FAIL_IF(!(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES), 
  108           "wrong server status: NO_BACKSLASH_ESCAPES not set");
  109 
  110   len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
  111   FAIL_IF(memcmp(out, "a''b\\c", len), "wrong result");
  112 
  113   return OK;
  114 }
  115 
  116 /*
  117  *  simple escaping of special chars
  118  */
  119 int test_escaping(MYSQL *mysql)
  120 {
  121   int i= 0, rc, len;
  122   char out[20];
  123   const char *escape_chars[] = {"'", "\x0", "\n", "\r", "\\", "\0", NULL};
  124 
  125   /* reset sql_mode, mysql_change_user call doesn't reset it */
  126   rc= mysql_query(mysql, "SET sql_mode=''");
  127   check_mysql_rc(rc, mysql);
  128 
  129   while (escape_chars[i]) {
  130     len= mysql_real_escape_string(mysql, out, escape_chars[i], 1);
  131     FAIL_IF(len < 2, "Len < 2");
  132     i++;
  133   }
  134 
  135   return OK;
  136 }
  137 
  138 /*
  139  * server doesn't reset sql_mode after COM_CHANGE_USER
  140  */
  141 int bug_41785(MYSQL *mysql)
  142 {
  143   char out[10];
  144   int rc, len;
  145 
  146   len= mysql_real_escape_string(mysql, out, "\\", 1);
  147   FAIL_IF(len != 2, "len != 2");
  148 
  149   rc= mysql_query(mysql, "SET SQL_MODE=NO_BACKSLASH_ESCAPES");
  150   check_mysql_rc(rc, mysql);
  151   rc= mysql_query(mysql, "SET sql_mode=''");
  152   check_mysql_rc(rc, mysql);
  153 
  154   mysql_change_user(mysql, "root", "", "test");
  155 
  156   len= mysql_real_escape_string(mysql, out, "\\", 1);
  157   FAIL_IF(len != 2, "len != 2");
  158 
  159   return OK;
  160 }
  161 
  162 static int test_conversion(MYSQL *mysql)
  163 {
  164   MYSQL_STMT *stmt;
  165   const char *stmt_text;
  166   int rc;
  167   MYSQL_BIND my_bind[1];
  168   uchar buff[4];
  169   ulong length;
  170 
  171   stmt_text= "DROP TABLE IF EXISTS t1";
  172   rc= mysql_real_query(mysql, SL(stmt_text));
  173   check_mysql_rc(rc, mysql);
  174   stmt_text= "CREATE TABLE t1 (a TEXT) DEFAULT CHARSET latin1";
  175   rc= mysql_real_query(mysql, SL(stmt_text));
  176   check_mysql_rc(rc, mysql);
  177   stmt_text= "SET character_set_connection=utf8, character_set_client=utf8, "
  178              " character_set_results=latin1";
  179   rc= mysql_real_query(mysql, SL(stmt_text));
  180   check_mysql_rc(rc, mysql);
  181 
  182   stmt= mysql_stmt_init(mysql);
  183   FAIL_IF(!stmt, mysql_error(mysql));
  184   stmt_text= "INSERT INTO t1 (a) VALUES (?)";
  185   rc= mysql_stmt_prepare(stmt, SL(stmt_text));
  186   check_stmt_rc(rc, stmt);
  187 
  188   memset(my_bind, '\0', sizeof(my_bind));
  189   my_bind[0].buffer= (char*) buff;
  190   my_bind[0].length= &length;
  191   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
  192 
  193   mysql_stmt_bind_param(stmt, my_bind);
  194 
  195   buff[0]= (uchar) 0xC3;
  196   buff[1]= (uchar) 0xA0;
  197   length= 2;
  198 
  199   rc= mysql_stmt_execute(stmt);
  200   check_stmt_rc(rc, stmt);
  201 
  202   stmt_text= "SELECT a FROM t1";
  203   rc= mysql_stmt_prepare(stmt, SL(stmt_text));
  204   check_stmt_rc(rc, stmt);
  205   rc= mysql_stmt_execute(stmt);
  206   check_stmt_rc(rc, stmt);
  207 
  208   my_bind[0].buffer_length= sizeof(buff);
  209   mysql_stmt_bind_result(stmt, my_bind);
  210 
  211   rc= mysql_stmt_fetch(stmt);
  212   check_stmt_rc(rc, stmt);
  213   FAIL_UNLESS(length == 1, "length != 1");
  214   FAIL_UNLESS(buff[0] == 0xE0, "buff[0] != 0xE0");
  215   rc= mysql_stmt_fetch(stmt);
  216   FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
  217 
  218   mysql_stmt_close(stmt);
  219   stmt_text= "DROP TABLE t1";
  220   rc= mysql_real_query(mysql, SL(stmt_text));
  221   check_mysql_rc(rc, mysql);
  222   stmt_text= "SET NAMES DEFAULT";
  223   rc= mysql_real_query(mysql, SL(stmt_text));
  224   check_mysql_rc(rc, mysql);
  225 
  226   return OK;
  227 }
  228 
  229 static int test_bug27876(MYSQL *mysql)
  230 {
  231   int rc;
  232   MYSQL_RES *result;
  233 
  234   uchar utf8_func[] =
  235   {
  236     0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba,
  237     0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba,
  238     0xd0, 0xb0,
  239     0x00
  240   };
  241 
  242   uchar utf8_param[] =
  243   {
  244     0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0,
  245     0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a,
  246     0xd1, 0x80, 0x5f, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1,
  247     0x80, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f,
  248     0x00
  249   };
  250 
  251   char query[500];
  252 
  253   rc= mysql_query(mysql, "set names utf8");
  254   check_mysql_rc(rc, mysql);
  255 
  256   rc= mysql_query(mysql, "select version()");
  257   check_mysql_rc(rc, mysql);
  258   result= mysql_store_result(mysql);
  259   FAIL_IF(!result, "Invalid result set");
  260   mysql_free_result(result);
  261 
  262   sprintf(query, "DROP FUNCTION IF EXISTS %s", (char*) utf8_func);
  263   rc= mysql_query(mysql, query);
  264   check_mysql_rc(rc, mysql);
  265 
  266   sprintf(query,
  267           "CREATE FUNCTION %s( %s VARCHAR(25))"
  268           " RETURNS VARCHAR(25) DETERMINISTIC RETURN %s",
  269           (char*) utf8_func, (char*) utf8_param, (char*) utf8_param);
  270   rc= mysql_query(mysql, query);
  271   check_mysql_rc(rc, mysql);
  272   sprintf(query, "SELECT %s(VERSION())", (char*) utf8_func);
  273   rc= mysql_query(mysql, query);
  274   check_mysql_rc(rc, mysql);
  275   result= mysql_store_result(mysql);
  276   FAIL_IF(!result, "Invalid result set");
  277   mysql_free_result(result);
  278 
  279   sprintf(query, "DROP FUNCTION %s", (char*) utf8_func);
  280   rc= mysql_query(mysql, query);
  281   check_mysql_rc(rc, mysql);
  282 
  283   rc= mysql_query(mysql, "set names default");
  284   check_mysql_rc(rc, mysql);
  285   return OK;
  286 }
  287 
  288 static int test_ps_i18n(MYSQL *mysql)
  289 {
  290   MYSQL_STMT *stmt;
  291   int rc;
  292   const char *stmt_text;
  293   MYSQL_BIND bind_array[2];
  294 
  295   /* Represented as numbers to keep UTF8 tools from clobbering them. */
  296   const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
  297   const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
  298   char buf1[16], buf2[16];
  299   ulong buf1_len, buf2_len;
  300 
  301   stmt_text= "DROP TABLE IF EXISTS t1";
  302   rc= mysql_real_query(mysql, SL(stmt_text));
  303   check_mysql_rc(rc, mysql);
  304 
  305   /*
  306     Create table with binary columns, set session character set to cp1251,
  307     client character set to koi8, and make sure that there is conversion
  308     on insert and no conversion on select
  309   */
  310 
  311   stmt_text= "CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))";
  312   rc= mysql_real_query(mysql, SL(stmt_text));
  313   check_mysql_rc(rc, mysql);
  314 
  315   stmt_text= "SET CHARACTER_SET_CLIENT=koi8r, "
  316                  "CHARACTER_SET_CONNECTION=cp1251, "
  317                  "CHARACTER_SET_RESULTS=koi8r";
  318 
  319   rc= mysql_real_query(mysql, SL(stmt_text));
  320   check_mysql_rc(rc, mysql);
  321 
  322   memset(bind_array, '\0', sizeof(bind_array));
  323   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
  324   bind_array[0].buffer= (void *) koi8;
  325   bind_array[0].buffer_length= (unsigned long)strlen(koi8);
  326 
  327   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
  328   bind_array[1].buffer= (void *) koi8;
  329   bind_array[1].buffer_length= (unsigned long)strlen(koi8);
  330 
  331   stmt= mysql_stmt_init(mysql);
  332   check_stmt_rc(rc, stmt);
  333 
  334   stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
  335 
  336   rc= mysql_stmt_prepare(stmt, SL(stmt_text));
  337   check_stmt_rc(rc, stmt);
  338   mysql_stmt_bind_param(stmt, bind_array);
  339   check_stmt_rc(rc, stmt);
  340 
  341 //  mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
  342 
  343   rc= mysql_stmt_execute(stmt);
  344   check_stmt_rc(rc, stmt);
  345   stmt_text= "SELECT c1, c2 FROM t1";
  346 
  347   /* c1 and c2 are binary so no conversion will be done on select */
  348   rc= mysql_stmt_prepare(stmt, SL(stmt_text));
  349   check_stmt_rc(rc, stmt);
  350   rc= mysql_stmt_execute(stmt);
  351   check_stmt_rc(rc, stmt);
  352   bind_array[0].buffer= buf1;
  353   bind_array[0].buffer_length= sizeof(buf1);
  354   bind_array[0].length= &buf1_len;
  355 
  356   bind_array[1].buffer= buf2;
  357   bind_array[1].buffer_length= sizeof(buf2);
  358   bind_array[1].length= &buf2_len;
  359 
  360   mysql_stmt_bind_result(stmt, bind_array);
  361 
  362   rc= mysql_stmt_fetch(stmt);
  363   check_stmt_rc(rc, stmt);
  364   FAIL_UNLESS(buf1_len == strlen(cp1251), "buf1_len != strlen(cp1251)");
  365   FAIL_UNLESS(buf2_len == strlen(cp1251), "buf2_len != strlen(cp1251)");
  366   FAIL_UNLESS(!memcmp(buf1, cp1251, buf1_len), "buf1 != cp1251");
  367   FAIL_UNLESS(!memcmp(buf2, cp1251, buf1_len), "buf2 != cp1251");
  368 
  369   rc= mysql_stmt_fetch(stmt);
  370   FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
  371 
  372   stmt_text= "DROP TABLE IF EXISTS t1";
  373   rc= mysql_real_query(mysql, SL(stmt_text));
  374   check_mysql_rc(rc, mysql);
  375 
  376   /*
  377     Now create table with two cp1251 columns, set client character
  378     set to koi8 and supply columns of one row as string and another as
  379     binary data. Binary data must not be converted on insert, and both
  380     columns must be converted to client character set on select.
  381   */
  382 
  383   stmt_text= "CREATE TABLE t1 (c1 VARCHAR(255) CHARACTER SET cp1251, "
  384                               "c2 VARCHAR(255) CHARACTER SET cp1251)";
  385 
  386   rc= mysql_real_query(mysql, SL(stmt_text));
  387   check_mysql_rc(rc, mysql);
  388 
  389   stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
  390 
  391   rc= mysql_stmt_prepare(stmt, SL(stmt_text));
  392   check_stmt_rc(rc, stmt);
  393   /* this data must be converted */
  394   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
  395   bind_array[0].buffer= (void *) koi8;
  396   bind_array[0].buffer_length= (unsigned long)strlen(koi8);
  397 
  398   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
  399   bind_array[1].buffer= (void *) koi8;
  400   bind_array[1].buffer_length= (unsigned long)strlen(koi8);
  401 
  402   mysql_stmt_bind_param(stmt, bind_array);
  403 
  404 //  mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
  405 
  406   rc= mysql_stmt_execute(stmt);
  407   check_stmt_rc(rc, stmt);
  408   /* this data must not be converted */
  409   bind_array[0].buffer_type= MYSQL_TYPE_BLOB;
  410   bind_array[0].buffer= (void *) cp1251;
  411   bind_array[0].buffer_length= (unsigned long)strlen(cp1251);
  412 
  413   bind_array[1].buffer_type= MYSQL_TYPE_BLOB;
  414   bind_array[1].buffer= (void *) cp1251;
  415   bind_array[1].buffer_length= (unsigned long)strlen(cp1251);
  416 
  417   mysql_stmt_bind_param(stmt, bind_array);
  418 
  419 //  mysql_stmt_send_long_data(stmt, 0, cp1251, strlen(cp1251));
  420 
  421   rc= mysql_stmt_execute(stmt);
  422   check_stmt_rc(rc, stmt);
  423   /* Fetch data and verify that rows are in koi8 */
  424 
  425   stmt_text= "SELECT c1, c2 FROM t1";
  426 
  427   /* c1 and c2 are binary so no conversion will be done on select */
  428   rc= mysql_stmt_prepare(stmt, SL(stmt_text));
  429   check_stmt_rc(rc, stmt);
  430   rc= mysql_stmt_execute(stmt);
  431   check_stmt_rc(rc, stmt);
  432   bind_array[0].buffer= buf1;
  433   bind_array[0].buffer_length= sizeof(buf1);
  434   bind_array[0].length= &buf1_len;
  435 
  436   bind_array[1].buffer= buf2;
  437   bind_array[1].buffer_length= sizeof(buf2);
  438   bind_array[1].length= &buf2_len;
  439 
  440   mysql_stmt_bind_result(stmt, bind_array);
  441 
  442   while ((rc= mysql_stmt_fetch(stmt)) == 0)
  443   {
  444     FAIL_UNLESS(buf1_len == strlen(koi8), "buf1_len != strlen(koi8)");
  445     FAIL_UNLESS(buf2_len == strlen(koi8), "buf2_len != strlen(koi8)");
  446     FAIL_UNLESS(!memcmp(buf1, koi8, buf1_len), "buf1 != koi8");
  447     FAIL_UNLESS(!memcmp(buf2, koi8, buf1_len), "buf2 != koi8");
  448   }
  449   FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
  450   mysql_stmt_close(stmt);
  451 
  452   stmt_text= "DROP TABLE t1";
  453   rc= mysql_real_query(mysql, SL(stmt_text));
  454   check_mysql_rc(rc, mysql);
  455   stmt_text= "SET NAMES DEFAULT";
  456   rc= mysql_real_query(mysql, SL(stmt_text));
  457   check_mysql_rc(rc, mysql);
  458   return OK;
  459 }
  460 
  461 /*
  462   Bug#30472: libmysql doesn't reset charset, insert_id after succ.
  463   mysql_change_user() call row insertions.
  464 */
  465 
  466 static int bug30472_retrieve_charset_info(MYSQL *con,
  467                                            char *character_set_name,
  468                                            char *character_set_client,
  469                                            char *character_set_results,
  470                                            char *collation_connection)
  471 {
  472   MYSQL_RES *rs;
  473   MYSQL_ROW row;
  474   int       rc;
  475 
  476   /* Get the cached client character set name. */
  477 
  478   strcpy(character_set_name, mysql_character_set_name(con));
  479 
  480   /* Retrieve server character set information. */
  481 
  482   rc= mysql_query(con, "SHOW VARIABLES LIKE 'character_set_client'");
  483   check_mysql_rc(rc, con);
  484 
  485   rs= mysql_store_result(con);
  486   FAIL_IF(!rs, "Invalid result set");
  487   row= mysql_fetch_row(rs);
  488   FAIL_IF(!row, "Couldn't fetch row");
  489   strcpy(character_set_client, row[1]);
  490   diag("cs: %s", row[1]);
  491   mysql_free_result(rs);
  492 
  493   rc= mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'");
  494   check_mysql_rc(rc, con);
  495   rs= mysql_store_result(con);
  496   FAIL_IF(!rs, "Invalid result set");
  497   row= mysql_fetch_row(rs);
  498   FAIL_IF(!row, "Couldn't fetch row");
  499   strcpy(character_set_results, row[1]);
  500   mysql_free_result(rs);
  501 
  502   rc= mysql_query(con, "SHOW VARIABLES LIKE 'collation_connection'");
  503   check_mysql_rc(rc, con);
  504   rs= mysql_store_result(con);
  505   FAIL_IF(!rs, "Invalid result set");
  506   row= mysql_fetch_row(rs);
  507   FAIL_IF(!row, "Couldn't fetch row");
  508   strcpy(collation_connection, row[1]);
  509   mysql_free_result(rs);
  510   return OK;
  511 }
  512 
  513 #define MY_CS_NAME_SIZE 32
  514 
  515 static int test_bug30472(MYSQL *mysql)
  516 {
  517   int   rc;
  518 
  519   char character_set_name_1[MY_CS_NAME_SIZE];
  520   char character_set_client_1[MY_CS_NAME_SIZE];
  521   char character_set_results_1[MY_CS_NAME_SIZE];
  522   char collation_connnection_1[MY_CS_NAME_SIZE];
  523 
  524   char character_set_name_2[MY_CS_NAME_SIZE];
  525   char character_set_client_2[MY_CS_NAME_SIZE];
  526   char character_set_results_2[MY_CS_NAME_SIZE];
  527   char collation_connnection_2[MY_CS_NAME_SIZE];
  528 
  529   char character_set_name_3[MY_CS_NAME_SIZE];
  530   char character_set_client_3[MY_CS_NAME_SIZE];
  531   char character_set_results_3[MY_CS_NAME_SIZE];
  532   char collation_connnection_3[MY_CS_NAME_SIZE];
  533 
  534   char character_set_name_4[MY_CS_NAME_SIZE];
  535   char character_set_client_4[MY_CS_NAME_SIZE];
  536   char character_set_results_4[MY_CS_NAME_SIZE];
  537   char collation_connnection_4[MY_CS_NAME_SIZE];
  538 
  539   if (mysql_get_server_version(mysql) < 50100 || !is_mariadb) 
  540   {
  541     diag("Test requires MySQL Server version 5.1 or above");
  542     return SKIP;
  543   }
  544   /* Retrieve character set information. */
  545 
  546   mysql_set_character_set(mysql, "latin1");
  547   bug30472_retrieve_charset_info(mysql,
  548                                  character_set_name_1,
  549                                  character_set_client_1,
  550                                  character_set_results_1,
  551                                  collation_connnection_1);
  552 
  553   /* Switch client character set. */
  554 
  555   FAIL_IF(mysql_set_character_set(mysql, "utf8"), "Setting cs to utf8 failed");
  556 
  557   /* Retrieve character set information. */
  558 
  559   bug30472_retrieve_charset_info(mysql,
  560                                  character_set_name_2,
  561                                  character_set_client_2,
  562                                  character_set_results_2,
  563                                  collation_connnection_2);
  564 
  565   /*
  566     Check that
  567       1) character set has been switched and
  568       2) new character set is different from the original one.
  569   */
  570 
  571   FAIL_UNLESS(strcmp(character_set_name_2, "utf8") == 0, "cs_name != utf8");
  572   FAIL_UNLESS(strcmp(character_set_client_2, "utf8") == 0, "cs_client != utf8");
  573   FAIL_UNLESS(strcmp(character_set_results_2, "utf8") == 0, "cs_result != ut8");
  574   FAIL_UNLESS(strcmp(collation_connnection_2, "utf8_general_ci") == 0, "collation != utf8_general_ci");
  575 
  576   diag("%s %s", character_set_name_1, character_set_name_2);
  577   FAIL_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0, "cs_name1 = cs_name2");
  578   FAIL_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0, "cs_client1 = cs_client2");
  579   FAIL_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0, "cs_result1 = cs_result2");
  580   FAIL_UNLESS(strcmp(collation_connnection_1, collation_connnection_2) != 0, "collation1 = collation2");
  581 
  582   /* Call mysql_change_user() with the same username, password, database. */
  583 
  584   rc= mysql_change_user(mysql, username, password, (schema) ? schema : "test");
  585   mysql_set_character_set(mysql, "latin1");
  586   check_mysql_rc(rc, mysql);
  587 
  588   /* Retrieve character set information. */
  589 
  590   bug30472_retrieve_charset_info(mysql,
  591                                  character_set_name_3,
  592                                  character_set_client_3,
  593                                  character_set_results_3,
  594                                  collation_connnection_3);
  595 
  596   /* Check that character set information has been reset. */
  597 
  598   FAIL_UNLESS(strcmp(character_set_name_1, character_set_name_3) == 0, "cs_name1 != cs_name3");
  599   FAIL_UNLESS(strcmp(character_set_client_1, character_set_client_3) == 0, "cs_client1 != cs_client3");
  600   FAIL_UNLESS(strcmp(character_set_results_1, character_set_results_3) == 0, "cs_result1 != cs_result3");
  601   FAIL_UNLESS(strcmp(collation_connnection_1, collation_connnection_3) == 0, "collation1 != collation3");
  602 
  603   /* Change connection-default character set in the client. */
  604 
  605   mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8");
  606 
  607   /*
  608     Call mysql_change_user() in order to check that new connection will
  609     have UTF8 character set on the client and on the server.
  610   */
  611 
  612   rc= mysql_change_user(mysql, username, password, (schema) ? schema : "test");
  613   check_mysql_rc(rc, mysql);
  614 
  615   /* Retrieve character set information. */
  616 
  617   bug30472_retrieve_charset_info(mysql,
  618                                  character_set_name_4,
  619                                  character_set_client_4,
  620                                  character_set_results_4,
  621                                  collation_connnection_4);
  622 
  623   /* Check that we have UTF8 on the server and on the client. */
  624 
  625   FAIL_UNLESS(strcmp(character_set_name_4, "utf8") == 0, "cs_name != utf8");
  626   FAIL_UNLESS(strcmp(character_set_client_4, "utf8") == 0, "cs_client != utf8");
  627   FAIL_UNLESS(strcmp(character_set_results_4, "utf8") == 0, "cs_result != utf8");
  628   FAIL_UNLESS(strcmp(collation_connnection_4, "utf8_general_ci") == 0, "collation_connection != utf8_general_ci");
  629 
  630   /* That's it. Cleanup. */
  631 
  632   return OK;
  633 }
  634 
  635 static int test_bug_54100(MYSQL *mysql)
  636 {
  637   MYSQL_RES *result;
  638   MYSQL_ROW row;
  639   int rc;
  640 
  641   rc= mysql_query(mysql, "SHOW CHARACTER SET");
  642   check_mysql_rc(rc, mysql);
  643   
  644   result= mysql_store_result(mysql);
  645 
  646   while ((row= mysql_fetch_row(result)))
  647   {
  648     /* ignore ucs2 */
  649     if (strcmp(row[0], "ucs2") && strcmp(row[0], "utf16le") && strcmp(row[0], "utf8mb4") && 
  650         strcmp(row[0], "utf16") && strcmp(row[0], "utf32")) {
  651       rc= mysql_set_character_set(mysql, row[0]);
  652       check_mysql_rc(rc, mysql);
  653     }
  654   }
  655   mysql_free_result(result);
  656 
  657   return OK;
  658 }
  659 
  660 
  661 /* We need this internal function for the test */
  662 
  663 static int test_utf16_utf32_noboms(MYSQL *mysql __attribute__((unused)))
  664 {
  665   const char *csname[]= {"utf16", "utf16le", "utf32", "utf8"};
  666   MARIADB_CHARSET_INFO  *csinfo[sizeof(csname)/sizeof(char*)];
  667 
  668   const int     UTF8= sizeof(csname)/sizeof(char*) - 1;
  669 
  670   unsigned char in_string[][8]= {"\xd8\x02\xdc\x60\0",      /* utf16(be) */
  671                                  "\x02\xd8\x60\xdc\0",      /* utf16le   */
  672                                  "\x00\x01\x08\x60\0\0\0",  /* utf32(be) */
  673                                  "\xF0\x90\xA1\xA0" };      /* utf8      */
  674   size_t       in_oct_len[]= {6, 6, 8, 5};
  675 
  676   char   buffer[8], as_hex[16];
  677   int    i, error;
  678   size_t rc, in_len, out_len;
  679 
  680   for (i= 0; i < (int)(sizeof(csname)/sizeof(char*)); ++i)
  681   {
  682     csinfo[i]= mariadb_get_charset_by_name(csname[i]);
  683 
  684     if (csinfo[i] == NULL)
  685     {
  686       diag("Could not get cs info for %s", csname[i]);
  687       return FAIL;
  688     }
  689   }
  690 
  691   for (i= 0; i < UTF8; ++i)
  692   {
  693     in_len=  in_oct_len[i];
  694     out_len= sizeof(buffer);
  695 
  696     diag("Converting %s->%s", csname[i], csname[UTF8]);
  697     rc= mariadb_convert_string((char *)in_string[i], &in_len, csinfo[i], buffer, &out_len, csinfo[UTF8], &error);
  698 
  699     FAIL_IF(rc == (size_t)-1, "Conversion failed");
  700     FAIL_IF(rc != in_oct_len[UTF8], "Incorrect number of written bytes");
  701 
  702     if (memcmp(buffer, in_string[UTF8], rc) != 0)
  703     {
  704       mysql_hex_string(as_hex, buffer, (unsigned long)rc);
  705       diag("Converted string(%s) does not match the expected one", as_hex);
  706       return FAIL;
  707     }
  708 
  709     in_len=  in_oct_len[UTF8];
  710     out_len= sizeof(buffer);
  711 
  712     diag("Converting %s->%s", csname[UTF8], csname[i]);
  713     rc= mariadb_convert_string((char *)in_string[UTF8], &in_len, csinfo[UTF8], buffer, &out_len, csinfo[i], &error);
  714 
  715     FAIL_IF(rc == (size_t)-1, "Conversion failed");
  716     diag("rc=%lu oct_len: %lu", (unsigned long)rc, (unsigned long)in_oct_len[i]);
  717     FAIL_IF(rc != in_oct_len[i], "Incorrect number of written bytes");
  718 
  719     if (memcmp(buffer, in_string[i], rc) != 0)
  720     {
  721       mysql_hex_string(as_hex, buffer, (unsigned long)rc);
  722       diag("Converted string(%s) does not match the expected one", as_hex);
  723       return FAIL;
  724     }
  725   }
  726 
  727   return OK;
  728 }
  729 
  730 static int charset_auto(MYSQL *my __attribute__((unused)))
  731 {
  732   const char *csname1, *csname2;
  733   const char *osname;
  734   MYSQL *mysql= mysql_init(NULL);
  735   int rc;
  736 
  737   osname= madb_get_os_character_set();
  738 
  739   mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "auto");
  740 
  741   FAIL_IF(!my_test_connect(mysql, hostname, username,
  742                              password, schema, port, socketname, 0), 
  743          mysql_error(mysql));
  744 
  745   csname1= mysql_character_set_name(mysql);
  746   diag("Character set: %s os charset: %s", csname1, osname);
  747 
  748   FAIL_IF(strcmp(osname, csname1), "character set is not os character set");
  749 
  750   if (strcmp(osname, "utf8"))
  751   {
  752     rc= mysql_set_character_set(mysql, "utf8");
  753     check_mysql_rc(rc, mysql);
  754 
  755     csname2= mysql_character_set_name(mysql);
  756     diag("Character set: %s", csname2);
  757 
  758     FAIL_IF(!strcmp(csname2, csname1), "Wrong charset: expected utf8");
  759 
  760     rc= mysql_set_character_set(mysql, "auto");
  761     check_mysql_rc(rc, mysql);
  762 
  763     csname2= mysql_character_set_name(mysql);
  764     diag("Character set: %s", csname2);
  765     FAIL_IF(strcmp(csname2, osname), "Wrong charset: expected os charset");
  766   }
  767   mysql_close(mysql);
  768   return OK;
  769 }
  770 
  771 /* check if all server character sets are supported */
  772 static int test_conc223(MYSQL *mysql)
  773 {
  774   int rc;
  775   MYSQL_RES *res;
  776   MYSQL_ROW row;
  777   int found= 0;
  778 
  779   rc= mysql_query(mysql, "SELECT ID, CHARACTER_SET_NAME, COLLATION_NAME FROM INFORMATION_SCHEMA.COLLATIONS");
  780   check_mysql_rc(rc, mysql);
  781 
  782   res= mysql_store_result(mysql);
  783   while ((row = mysql_fetch_row(res)))
  784   {
  785     int id= atoi(row[0]);
  786     if (!mariadb_get_charset_by_nr(id))
  787     {
  788       diag("%04d %s %s", id, row[1], row[2]);
  789       found++;
  790     }
  791   }
  792   mysql_free_result(res);
  793   if (found)
  794   {
  795     diag("%d character sets/collations not found", found);
  796     return FAIL;
  797   }
  798   return OK;
  799 }
  800 
  801 struct my_tests_st my_tests[] = {
  802   {"test_conc223", test_conc223, TEST_CONNECTION_DEFAULT, 0,  NULL, NULL},
  803   {"charset_auto", charset_auto, TEST_CONNECTION_DEFAULT, 0,  NULL, NULL},
  804   {"bug_8378: mysql_real_escape with gbk", bug_8378, TEST_CONNECTION_NEW, 0,  opt_bug8378,  NULL},
  805   {"test_client_character_set", test_client_character_set, TEST_CONNECTION_DEFAULT, 0,  NULL,  NULL},
  806   {"bug_10214: mysql_real_escape with NO_BACKSLASH_ESCAPES", bug_10214, TEST_CONNECTION_DEFAULT, 0,  NULL, NULL},
  807   {"test_escaping", test_escaping, TEST_CONNECTION_DEFAULT, 0,  NULL, NULL}, 
  808   {"test_conversion", test_conversion, TEST_CONNECTION_DEFAULT, 0,  NULL, NULL},
  809   {"bug_41785", bug_41785, TEST_CONNECTION_DEFAULT, 0,  NULL, "not fixed yet"},
  810   {"test_bug27876", test_bug27876, TEST_CONNECTION_DEFAULT, 0,  NULL, NULL},
  811   {"test_bug30472", test_bug30472, TEST_CONNECTION_NEW, 0,  NULL, NULL},
  812   {"test_ps_i18n", test_ps_i18n, TEST_CONNECTION_DEFAULT, 0,  NULL, NULL},
  813   {"test_bug_54100", test_bug_54100, TEST_CONNECTION_NEW, 0, NULL, NULL}, 
  814   {"test_utf16_utf32_noboms", test_utf16_utf32_noboms, TEST_CONNECTION_DEFAULT, 0,  NULL, NULL},
  815   {NULL, NULL, 0, 0, NULL, 0}
  816 };
  817 
  818 
  819 int main(int argc, char **argv)
  820 {
  821   if (argc > 1)
  822    get_options(argc, argv);
  823 
  824   get_envvars();
  825 
  826   run_tests(my_tests);
  827 
  828   return(exit_status());
  829 }