summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2016-08-03 20:38:25 +0200
committerSergei Golubchik <serg@mariadb.org>2016-08-03 20:38:25 +0200
commita350e53b611f436ad7ac618d6fde777dd457a3fe (patch)
treebc6ab938b6d1776d5f1d5f0894b8ba22bc2b6934
parent511313b9d640b8e4b2860980e79889f125d3cd5e (diff)
parent7d57772f47e0d69b2e2a7bcd62da59e54f8c8343 (diff)
downloadmariadb-git-a350e53b611f436ad7ac618d6fde777dd457a3fe.tar.gz
Merge branch 'mysql/5.5' into 5.5
without a fix for Bug#12818255 (MDEV-6581)
-rw-r--r--client/mysqlimport.c58
-rw-r--r--mysql-test/r/func_misc.result7
-rw-r--r--mysql-test/r/loaddata.result26
-rw-r--r--mysql-test/r/sp-prelocking.result20
-rw-r--r--mysql-test/std_data/bug20683959loaddata.txt1
-rw-r--r--mysql-test/suite/binlog/r/binlog_dmls_on_tmp_tables_readonly.result58
-rw-r--r--mysql-test/suite/binlog/t/binlog_dmls_on_tmp_tables_readonly.test91
-rw-r--r--mysql-test/t/func_misc.test10
-rw-r--r--mysql-test/t/loaddata.test25
-rw-r--r--mysql-test/t/sp-prelocking.test26
-rw-r--r--regex/split.c4
-rw-r--r--sql/sql_base.cc11
-rw-r--r--sql/sql_load.cc77
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);