diff options
-rw-r--r-- | client/mysqlimport.c | 58 | ||||
-rw-r--r-- | mysql-test/r/func_misc.result | 7 | ||||
-rw-r--r-- | mysql-test/r/loaddata.result | 26 | ||||
-rw-r--r-- | mysql-test/r/sp-prelocking.result | 20 | ||||
-rw-r--r-- | mysql-test/std_data/bug20683959loaddata.txt | 1 | ||||
-rw-r--r-- | mysql-test/suite/binlog/r/binlog_dmls_on_tmp_tables_readonly.result | 58 | ||||
-rw-r--r-- | mysql-test/suite/binlog/t/binlog_dmls_on_tmp_tables_readonly.test | 91 | ||||
-rw-r--r-- | mysql-test/t/func_misc.test | 10 | ||||
-rw-r--r-- | mysql-test/t/loaddata.test | 25 | ||||
-rw-r--r-- | mysql-test/t/sp-prelocking.test | 26 | ||||
-rw-r--r-- | regex/split.c | 4 | ||||
-rw-r--r-- | sql/sql_base.cc | 11 | ||||
-rw-r--r-- | sql/sql_load.cc | 77 |
13 files changed, 373 insertions, 41 deletions
diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 8fab3f28cf3..850a851b4aa 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -37,6 +37,7 @@ /* Global Thread counter */ uint counter= 0; +pthread_mutex_t init_mutex; pthread_mutex_t counter_mutex; pthread_cond_t count_threshhold; @@ -421,8 +422,19 @@ static MYSQL *db_connect(char *host, char *database, MYSQL *mysql; if (verbose) fprintf(stdout, "Connecting to %s\n", host ? host : "localhost"); - if (!(mysql= mysql_init(NULL))) - return 0; + if (opt_use_threads && !lock_tables) + { + pthread_mutex_lock(&init_mutex); + if (!(mysql= mysql_init(NULL))) + { + pthread_mutex_unlock(&init_mutex); + return 0; + } + pthread_mutex_unlock(&init_mutex); + } + else + if (!(mysql= mysql_init(NULL))) + return 0; if (opt_compress) mysql_options(mysql,MYSQL_OPT_COMPRESS,NullS); if (opt_local_file) @@ -605,7 +617,7 @@ error: pthread_cond_signal(&count_threshhold); pthread_mutex_unlock(&counter_mutex); mysql_thread_end(); - + pthread_exit(0); return 0; } @@ -629,15 +641,31 @@ int main(int argc, char **argv) if (opt_use_threads && !lock_tables) { - pthread_t mainthread; /* Thread descriptor */ - pthread_attr_t attr; /* Thread attributes */ + char **save_argv; + uint worker_thread_count= 0, table_count= 0, i= 0; + pthread_t *worker_threads; /* Thread descriptor */ + pthread_attr_t attr; /* Thread attributes */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, - PTHREAD_CREATE_DETACHED); + PTHREAD_CREATE_JOINABLE); + pthread_mutex_init(&init_mutex, NULL); pthread_mutex_init(&counter_mutex, NULL); pthread_cond_init(&count_threshhold, NULL); + /* Count the number of tables. This number denotes the total number + of threads spawn. + */ + save_argv= argv; + for (table_count= 0; *argv != NULL; argv++) + table_count++; + argv= save_argv; + + if (!(worker_threads= (pthread_t*) my_malloc(table_count * + sizeof(*worker_threads), + MYF(0)))) + return -2; + for (counter= 0; *argv != NULL; argv++) /* Loop through tables */ { pthread_mutex_lock(&counter_mutex); @@ -652,15 +680,16 @@ int main(int argc, char **argv) counter++; pthread_mutex_unlock(&counter_mutex); /* now create the thread */ - if (pthread_create(&mainthread, &attr, worker_thread, - (void *)*argv) != 0) + if (pthread_create(&worker_threads[worker_thread_count], &attr, + worker_thread, (void *)*argv) != 0) { pthread_mutex_lock(&counter_mutex); counter--; pthread_mutex_unlock(&counter_mutex); - fprintf(stderr,"%s: Could not create thread\n", - my_progname); + fprintf(stderr,"%s: Could not create thread\n", my_progname); + continue; } + worker_thread_count++; } /* @@ -675,9 +704,18 @@ int main(int argc, char **argv) pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime); } pthread_mutex_unlock(&counter_mutex); + pthread_mutex_destroy(&init_mutex); pthread_mutex_destroy(&counter_mutex); pthread_cond_destroy(&count_threshhold); pthread_attr_destroy(&attr); + + for(i= 0; i < worker_thread_count; i++) + { + if (pthread_join(worker_threads[i], NULL)) + fprintf(stderr,"%s: Could not join worker thread.\n", my_progname); + } + + my_free(worker_threads); } else { diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index a121bd324ee..1c106acf333 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -574,3 +574,10 @@ drop table t1; # # End of 5.5 tests # +SELECT NAME_CONST('a', -(1 OR 2)) OR 1; +ERROR HY000: Incorrect arguments to NAME_CONST +SELECT NAME_CONST('a', -(1 AND 2)) OR 1; +ERROR HY000: Incorrect arguments to NAME_CONST +SELECT NAME_CONST('a', -(1)) OR 1; +NAME_CONST('a', -(1)) OR 1 +1 diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result index 8ccc1a3da3d..ba5c763fbda 100644 --- a/mysql-test/r/loaddata.result +++ b/mysql-test/r/loaddata.result @@ -507,7 +507,7 @@ DROP TABLE t1; # Bug#11765139 58069: LOAD DATA INFILE: VALGRIND REPORTS INVALID MEMORY READS AND WRITES WITH U # CREATE TABLE t1(f1 INT); -SELECT 0xE1BB30 INTO OUTFILE 't1.dat'; +SELECT 0xE1C330 INTO OUTFILE 't1.dat'; LOAD DATA INFILE 't1.dat' IGNORE INTO TABLE t1 CHARACTER SET utf8; DROP TABLE t1; # @@ -532,3 +532,27 @@ FIELDS TERMINATED BY 't' LINES TERMINATED BY ''; Got one of the listed errors SET @@sql_mode= @old_mode; DROP TABLE t1; + +# +# Bug#23080148 - Backport of Bug#20683959. +# Bug#20683959 LOAD DATA INFILE IGNORES A SPECIFIC ROW SILENTLY +# UNDER DB CHARSET IS UTF8. +# +CREATE DATABASE d1 CHARSET latin1; +USE d1; +CREATE TABLE t1 (val TEXT); +LOAD DATA INFILE '../../std_data/bug20683959loaddata.txt' INTO TABLE t1; +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +SELECT HEX(val) FROM t1; +HEX(val) +C38322525420406E696F757A656368756E3A20E98198E2889AF58081AEE7B99DE4B88AE383A3E7B99DE69690F58087B3E7B9A7EFBDA8E7B99DEFBDB3E7B99DE78999E880B3E7B8BAEFBDAAE7B9A7E89699E296A1E7B8BAE4BBA3EFBD8CE7B8BAEFBDA9E7B8B2E2889AE38184E7B99DEFBDB3E7B99DE4B88AE383A3E7B99DE69690F58087B3E7B9A7EFBDA8E7B99DEFBDB3E7B99DE5B3A8EFBD84E8ABA0EFBDA8E89C89F580948EE599AAE7B8BAEFBDAAE7B8BAE9A198EFBDA9EFBDB1E7B9A7E581B5E289A0E7B8BAEFBDBEE7B9A7E9A194EFBDA9E882B4EFBDA5EFBDB5E980A7F5808B96E28693E99EABE38287E58F99E7B8BAE58AB1E28691E7B8BAF5808B9AE7828AE98095EFBDB1E7B8BAEFBDAFE7B8B2E288ABE6A89FE89EB3E6BA98F58081ADE88EA0EFBDBAE98095E6BA98F58081AEE89D93EFBDBAE8AD9BEFBDACE980A7F5808B96E28693E7B8BAF580918EE288AAE7B8BAE4B88AEFBC9EE7B8BAE4B99DE28691E7B8BAF5808B96EFBCA0E88DB3E6A68AEFBDB9EFBDB3E981B2E5B3A8E296A1E7B8BAE7A4BCE7828AE88DB3E6A68AEFBDB0EFBDBDE7B8BAA0E7B8BAE88B93EFBDBEE5B899EFBC9E +CREATE DATABASE d2 CHARSET utf8; +USE d2; +CREATE TABLE t1 (val TEXT); +LOAD DATA INFILE '../../std_data/bug20683959loaddata.txt' INTO TABLE t1; +ERROR HY000: Invalid utf8 character string: 'Ã"RT @niouzechun: \9058\221A' +DROP TABLE d1.t1, d2.t1; +DROP DATABASE d1; +DROP DATABASE d2; diff --git a/mysql-test/r/sp-prelocking.result b/mysql-test/r/sp-prelocking.result index 186b2c05d34..ac48459b0f2 100644 --- a/mysql-test/r/sp-prelocking.result +++ b/mysql-test/r/sp-prelocking.result @@ -320,3 +320,23 @@ c2 DROP TRIGGER t1_ai; DROP TABLE t1, t2; End of 5.0 tests +# +# Bug#21142859: FUNCTION UPDATING A VIEW FAILS TO FIND TABLE THAT ACTUALLY EXISTS +# +CREATE TABLE t1 SELECT 1 AS fld1, 'A' AS fld2; +CREATE TABLE t2 (fld3 INT, fld4 CHAR(1)); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TRIGGER t1_au AFTER UPDATE ON t1 +FOR EACH ROW INSERT INTO t2 VALUES (new.fld1, new.fld2); +CREATE FUNCTION f1() RETURNS INT +BEGIN +UPDATE v1 SET fld2='B' WHERE fld1=1; +RETURN row_count(); +END ! +# Without the patch, an error was getting reported. +SELECT f1(); +f1() +1 +DROP FUNCTION f1; +DROP VIEW v1; +DROP TABLE t1,t2; diff --git a/mysql-test/std_data/bug20683959loaddata.txt b/mysql-test/std_data/bug20683959loaddata.txt new file mode 100644 index 00000000000..1878cc78879 --- /dev/null +++ b/mysql-test/std_data/bug20683959loaddata.txt @@ -0,0 +1 @@ +Ã"RT @niouzechun: é˜âˆšõ€®ç¹ä¸Šãƒ£ç¹æ–õ€‡³ç¹§ï½¨ç¹ï½³ç¹ç‰™è€³ç¸ºï½ªç¹§è–™â–¡ç¸ºä»£ï½Œç¸ºï½©ç¸²âˆšã„ç¹ï½³ç¹ä¸Šãƒ£ç¹æ–õ€‡³ç¹§ï½¨ç¹ï½³ç¹å³¨ï½„è« ï½¨èœ‰õ€”Žå™ªç¸ºï½ªç¸ºé¡˜ï½©ï½±ç¹§åµâ‰ 縺セ繧顔ゥ肴・オ逧õ€‹–↓鞫ょå™ç¸ºåŠ±â†‘縺õ€‹šç‚Šé€•ï½±ç¸ºï½¯ç¸²âˆ«æ¨Ÿèž³æº˜õ€èŽ コ逕溘õ€®è“コè›ï½¬é€§õ€‹–↓縺õ€‘Žâˆªç¸ºä¸Šï¼žç¸ºä¹â†‘縺õ€‹–ï¼ è³æ¦Šï½¹ï½³é²å³¨â–¡ç¸ºç¤¼ç‚Šè³æ¦Šï½°ï½½ç¸º 縺苓セ帙> diff --git a/mysql-test/suite/binlog/r/binlog_dmls_on_tmp_tables_readonly.result b/mysql-test/suite/binlog/r/binlog_dmls_on_tmp_tables_readonly.result new file mode 100644 index 00000000000..1dfac08e762 --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_dmls_on_tmp_tables_readonly.result @@ -0,0 +1,58 @@ +DROP TABLE IF EXISTS t1 ; +# READ_ONLY does nothing to SUPER users +# so we use a non-SUPER one: +GRANT CREATE, SELECT, DROP ON *.* TO test@localhost; +connect con1,localhost,test,,test; +connection default; +SET GLOBAL READ_ONLY=1; +connection con1; +CREATE TEMPORARY TABLE t1 (a INT) ENGINE=INNODB; +# Test INSERTS with autocommit being off and on. +BEGIN; +INSERT INTO t1 VALUES (10); +COMMIT; +INSERT INTO t1 VALUES (20); +# Test UPDATES with autocommit being off and on. +BEGIN; +UPDATE t1 SET a=30 WHERE a=10; +COMMIT; +UPDATE t1 SET a=40 WHERE a=20; +connection default; +SET GLOBAL READ_ONLY=0; +# Test scenario where global read_only is enabled in the middle of transaction. +# Test INSERT operations on temporary tables, INSERTs should be successful even +# when global read_only is enabled. +connection con1; +BEGIN; +INSERT INTO t1 VALUES(50); +connection default; +SET GLOBAL READ_ONLY=1; +connection con1; +SELECT @@GLOBAL.READ_ONLY; +@@GLOBAL.READ_ONLY +1 +COMMIT; +connection default; +SET GLOBAL READ_ONLY=0; +# Test UPDATE operations on temporary tables, UPDATEs should be successful even +# when global read_only is enabled. +connection con1; +BEGIN; +UPDATE t1 SET a=60 WHERE a=50; +connection default; +SET GLOBAL READ_ONLY=1; +connection con1; +SELECT @@GLOBAL.READ_ONLY; +@@GLOBAL.READ_ONLY +1 +COMMIT; +SELECT * FROM t1; +a +30 +40 +60 +# Clean up +connection default; +SET GLOBAL READ_ONLY=0; +disconnect con1; +DROP USER test@localhost; diff --git a/mysql-test/suite/binlog/t/binlog_dmls_on_tmp_tables_readonly.test b/mysql-test/suite/binlog/t/binlog_dmls_on_tmp_tables_readonly.test new file mode 100644 index 00000000000..cf3910eb229 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_dmls_on_tmp_tables_readonly.test @@ -0,0 +1,91 @@ +# ==== Purpose ==== +# +# Check that DMLs are allowed on temporary tables, when server is in read only +# mode and binary log is enabled with binlog-format being stmt/mixed mode. +# +# ==== Implementation ==== +# +# Start the server with binary log being enabled. Mark the server as read only. +# Create a non-SUPER user and let the user to create a temporary table and +# perform DML operations on that temporary table. DMLs should not be blocked +# with a 'server read-only mode' error. +# +# ==== References ==== +# +# Bug#12818255: READ-ONLY OPTION DOES NOT ALLOW INSERTS/UPDATES ON TEMPORARY +# TABLES +# Bug#14294223: CHANGES NOT ALLOWED TO TEMPORARY TABLES ON READ-ONLY SERVERS +############################################################################### +--source include/have_log_bin.inc +--source include/have_innodb.inc +--disable_warnings +DROP TABLE IF EXISTS t1 ; +--enable_warnings + +--enable_connect_log +--echo # READ_ONLY does nothing to SUPER users +--echo # so we use a non-SUPER one: +GRANT CREATE, SELECT, DROP ON *.* TO test@localhost; + +connect (con1,localhost,test,,test); + +connection default; +SET GLOBAL READ_ONLY=1; + +connection con1; +CREATE TEMPORARY TABLE t1 (a INT) ENGINE=INNODB; + +--echo # Test INSERTS with autocommit being off and on. +BEGIN; +INSERT INTO t1 VALUES (10); +COMMIT; +INSERT INTO t1 VALUES (20); + +--echo # Test UPDATES with autocommit being off and on. +BEGIN; +UPDATE t1 SET a=30 WHERE a=10; +COMMIT; +UPDATE t1 SET a=40 WHERE a=20; + +connection default; +SET GLOBAL READ_ONLY=0; + +--echo # Test scenario where global read_only is enabled in the middle of transaction. +--echo # Test INSERT operations on temporary tables, INSERTs should be successful even +--echo # when global read_only is enabled. +connection con1; +BEGIN; +INSERT INTO t1 VALUES(50); + +connection default; +SET GLOBAL READ_ONLY=1; + +connection con1; +SELECT @@GLOBAL.READ_ONLY; +COMMIT; + +connection default; +SET GLOBAL READ_ONLY=0; + +--echo # Test UPDATE operations on temporary tables, UPDATEs should be successful even +--echo # when global read_only is enabled. +connection con1; +BEGIN; +UPDATE t1 SET a=60 WHERE a=50; + +connection default; +SET GLOBAL READ_ONLY=1; + +connection con1; +SELECT @@GLOBAL.READ_ONLY; +COMMIT; + +SELECT * FROM t1; + +--echo # Clean up +connection default; +SET GLOBAL READ_ONLY=0; + +disconnect con1; +DROP USER test@localhost; +--disable_connect_log diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 5991220e273..d7eda5ee4e6 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -599,3 +599,13 @@ drop table t1; --echo # --echo # End of 5.5 tests --echo # + +# +# Bug#12735545 - PARSER STACK OVERFLOW WITH NAME_CONST +# CONTAINING OR EXPRESSION +# +--error ER_WRONG_ARGUMENTS +SELECT NAME_CONST('a', -(1 OR 2)) OR 1; +--error ER_WRONG_ARGUMENTS +SELECT NAME_CONST('a', -(1 AND 2)) OR 1; +SELECT NAME_CONST('a', -(1)) OR 1; diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test index 35243864c04..7d0f3852b66 100644 --- a/mysql-test/t/loaddata.test +++ b/mysql-test/t/loaddata.test @@ -612,7 +612,7 @@ disconnect con1; --echo # CREATE TABLE t1(f1 INT); -EVAL SELECT 0xE1BB30 INTO OUTFILE 't1.dat'; +EVAL SELECT 0xE1C330 INTO OUTFILE 't1.dat'; --disable_warnings LOAD DATA INFILE 't1.dat' IGNORE INTO TABLE t1 CHARACTER SET utf8; --enable_warnings @@ -658,3 +658,26 @@ SET @@sql_mode= @old_mode; --remove_file $MYSQLTEST_VARDIR/mysql DROP TABLE t1; +--echo +--echo # +--echo # Bug#23080148 - Backport of Bug#20683959. +--echo # Bug#20683959 LOAD DATA INFILE IGNORES A SPECIFIC ROW SILENTLY +--echo # UNDER DB CHARSET IS UTF8. +--echo # + +CREATE DATABASE d1 CHARSET latin1; +USE d1; +CREATE TABLE t1 (val TEXT); +LOAD DATA INFILE '../../std_data/bug20683959loaddata.txt' INTO TABLE t1; +SELECT COUNT(*) FROM t1; +SELECT HEX(val) FROM t1; + +CREATE DATABASE d2 CHARSET utf8; +USE d2; +CREATE TABLE t1 (val TEXT); +--error ER_INVALID_CHARACTER_STRING +LOAD DATA INFILE '../../std_data/bug20683959loaddata.txt' INTO TABLE t1; + +DROP TABLE d1.t1, d2.t1; +DROP DATABASE d1; +DROP DATABASE d2; diff --git a/mysql-test/t/sp-prelocking.test b/mysql-test/t/sp-prelocking.test index 966c59a5789..c1378d59196 100644 --- a/mysql-test/t/sp-prelocking.test +++ b/mysql-test/t/sp-prelocking.test @@ -388,3 +388,29 @@ DROP TABLE t1, t2; --echo End of 5.0 tests +--echo # +--echo # Bug#21142859: FUNCTION UPDATING A VIEW FAILS TO FIND TABLE THAT ACTUALLY EXISTS +--echo # + +CREATE TABLE t1 SELECT 1 AS fld1, 'A' AS fld2; +CREATE TABLE t2 (fld3 INT, fld4 CHAR(1)); + +CREATE VIEW v1 AS SELECT * FROM t1; + +CREATE TRIGGER t1_au AFTER UPDATE ON t1 +FOR EACH ROW INSERT INTO t2 VALUES (new.fld1, new.fld2); + +DELIMITER !; +CREATE FUNCTION f1() RETURNS INT +BEGIN + UPDATE v1 SET fld2='B' WHERE fld1=1; + RETURN row_count(); +END ! +DELIMITER ;! + +--echo # Without the patch, an error was getting reported. +SELECT f1(); + +DROP FUNCTION f1; +DROP VIEW v1; +DROP TABLE t1,t2; diff --git a/regex/split.c b/regex/split.c index a3a11f793ed..abae74eba9c 100644 --- a/regex/split.c +++ b/regex/split.c @@ -159,6 +159,10 @@ char *argv[]; if (argc > 4) for (n = atoi(argv[3]); n > 0; n--) { + if(sizeof(buf)-1 < strlen(argv[1])) + { + exit(EXIT_FAILURE); + } (void) strcpy(buf, argv[1]); } else if (argc > 3) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index cb302de35f9..d281758fc18 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. Copyright (c) 2010, 2016, MariaDB This program is free software; you can redistribute it and/or modify @@ -5371,6 +5371,15 @@ handle_view(THD *thd, Query_tables_list *prelocking_ctx, &table_list->view->sroutines_list, table_list->top_table()); } + + /* + If a trigger was defined on one of the associated tables then assign the + 'trg_event_map' value of the view to the next table in table_list. When a + Stored function is invoked, all the associated tables including the tables + associated with the trigger are prelocked. + */ + if (table_list->trg_event_map && table_list->next_global) + table_list->next_global->trg_event_map= table_list->trg_event_map; return FALSE; } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index fba6dcf9ac0..9f300f803de 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -1389,8 +1389,8 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs, set_if_bigger(length,line_start.length()); stack=stack_pos=(int*) sql_alloc(sizeof(int)*length); - if (!(buffer=(uchar*) my_malloc(buff_length+1,MYF(0)))) - error=1; /* purecov: inspected */ + if (!(buffer=(uchar*) my_malloc(buff_length+1,MYF(MY_WME)))) + error= true; /* purecov: inspected */ else { end_of_buff=buffer+buff_length; @@ -1581,37 +1581,50 @@ int READ_INFO::read_field() } } #ifdef USE_MB - if (my_mbcharlen(read_charset, chr) > 1 && - to + my_mbcharlen(read_charset, chr) <= end_of_buff) - { - uchar* p= to; - int ml, i; - *to++ = chr; - - ml= my_mbcharlen(read_charset, chr); + uint ml= my_mbcharlen(read_charset, chr); + if (ml == 0) + { + *to= '\0'; + my_error(ER_INVALID_CHARACTER_STRING, MYF(0), + read_charset->csname, buffer); + error= true; + return 1; + } - for (i= 1; i < ml; i++) + if (ml > 1 && + to + ml <= end_of_buff) { - chr= GET; - if (chr == my_b_EOF) + uchar* p= to; + *to++ = chr; + + for (uint i= 1; i < ml; i++) { - /* - Need to back up the bytes already ready from illformed - multi-byte char - */ - to-= i; - goto found_eof; + chr= GET; + if (chr == my_b_EOF) + { + /* + Need to back up the bytes already ready from illformed + multi-byte char + */ + to-= i; + goto found_eof; + } + *to++ = chr; } - *to++ = chr; - } - if (my_ismbchar(read_charset, + if (my_ismbchar(read_charset, (const char *)p, (const char *)to)) - continue; - for (i= 0; i < ml; i++) - PUSH(*--to); - chr= GET; - } + continue; + for (uint i= 0; i < ml; i++) + PUSH(*--to); + chr= GET; + } + else if (ml > 1) + { + // Buffer is too small, exit while loop, and reallocate. + PUSH(chr); + break; + } #endif *to++ = (uchar) chr; } @@ -1855,7 +1868,15 @@ int READ_INFO::read_value(int delim, String *val) for (chr= GET; my_tospace(chr) != delim && chr != my_b_EOF;) { #ifdef USE_MB - if (my_mbcharlen(read_charset, chr) > 1) + uint ml= my_mbcharlen(read_charset, chr); + if (ml == 0) + { + chr= my_b_EOF; + val->length(0); + return chr; + } + + if (ml > 1) { DBUG_PRINT("read_xml",("multi byte")); int i, ml= my_mbcharlen(read_charset, chr); |