Merge from mysql-5.1.57-release

This commit is contained in:
Karen Langford 2011-05-06 10:03:02 +02:00
commit 83f19ef457
12 changed files with 333 additions and 37 deletions

View File

@ -12756,3 +12756,19 @@ a
1 1
2 2
DROP TABLE t1; DROP TABLE t1;
#
# BUG#57162 - valgrind errors, random data when returning
# ordered data from archive tables
#
SET sort_buffer_size=32804;
CREATE TABLE t1(a INT, b CHAR(255), c CHAR(255), d CHAR(255),
e CHAR(255), f INT) ENGINE=ARCHIVE DEFAULT CHARSET utf8;
INSERT INTO t1 VALUES(-1,'b','c','d','e',1);
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT t1.* FROM t1,t1 t2,t1 t3,t1 t4,t1 t5,t1 t6;
SELECT * FROM t1 ORDER BY f LIMIT 1;
a b c d e f
-1 b c d e 1
DROP TABLE t1;
SET sort_buffer_size=DEFAULT;

View File

@ -451,4 +451,21 @@ SELECT CONVERT(t2.a USING UTF8) FROM t1, t1 t2 LIMIT 1
1 1
1 1
DROP TABLE t1; DROP TABLE t1;
#
# Bug #11765023: 57934: DOS POSSIBLE SINCE BINARY CASTING
# DOESN'T ADHERE TO MAX_ALLOWED_PACKET
SET @@GLOBAL.max_allowed_packet=2048;
Warnings:
Warning 1105 The value of 'max_allowed_packet' should be no less than the value of 'net_buffer_length'
SELECT CONVERT('a', BINARY(2049));
CONVERT('a', BINARY(2049))
NULL
Warnings:
Warning 1301 Result of cast_as_binary() was larger than max_allowed_packet (2048) - truncated
SELECT CONVERT('a', CHAR(2049));
CONVERT('a', CHAR(2049))
NULL
Warnings:
Warning 1301 Result of cast_as_char() was larger than max_allowed_packet (2048) - truncated
SET @@GLOBAL.max_allowed_packet=default;
End of 5.1 tests End of 5.1 tests

View File

@ -1040,6 +1040,39 @@ drop table t1;
# #
create table t1(a char(32) not null) engine=myisam; create table t1(a char(32) not null) engine=myisam;
create spatial index i on t1 (a); create spatial index i on t1 (a);
ERROR HY000: Can't create table '#sql-temporary' (errno: 140) ERROR HY000: Incorrect arguments to SPATIAL INDEX
drop table t1; drop table t1;
CREATE TABLE t0 (a BINARY(32) NOT NULL);
CREATE SPATIAL INDEX i on t0 (a);
ERROR HY000: Incorrect arguments to SPATIAL INDEX
INSERT INTO t0 VALUES (1);
CREATE TABLE t1(
col0 BINARY NOT NULL,
col2 TIMESTAMP,
SPATIAL INDEX i1 (col0)
) ENGINE=MyISAM;
ERROR HY000: Incorrect arguments to SPATIAL INDEX
CREATE TABLE t1 (
col0 BINARY NOT NULL,
col2 TIMESTAMP
) ENGINE=MyISAM;
CREATE SPATIAL INDEX idx0 ON t1(col0);
ERROR HY000: Incorrect arguments to SPATIAL INDEX
ALTER TABLE t1 ADD SPATIAL INDEX i1 (col0);
ERROR HY000: Incorrect arguments to SPATIAL INDEX
CREATE TABLE t2 (
col0 INTEGER NOT NULL,
col1 POINT,
col2 POINT
);
CREATE SPATIAL INDEX idx0 ON t2 (col1, col2);
ERROR HY000: Incorrect arguments to SPATIAL INDEX
CREATE TABLE t3 (
col0 INTEGER NOT NULL,
col1 POINT,
col2 LINESTRING,
SPATIAL INDEX i1 (col1, col2)
);
ERROR HY000: Incorrect arguments to SPATIAL INDEX
DROP TABLE t0, t1, t2;
End of 5.1 tests End of 5.1 tests

View File

@ -1678,3 +1678,18 @@ SELECT * FROM t1;
REPAIR TABLE t1 EXTENDED; REPAIR TABLE t1 EXTENDED;
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # BUG#57162 - valgrind errors, random data when returning
--echo # ordered data from archive tables
--echo #
SET sort_buffer_size=32804;
CREATE TABLE t1(a INT, b CHAR(255), c CHAR(255), d CHAR(255),
e CHAR(255), f INT) ENGINE=ARCHIVE DEFAULT CHARSET utf8;
INSERT INTO t1 VALUES(-1,'b','c','d','e',1);
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT t1.* FROM t1,t1 t2,t1 t3,t1 t4,t1 t5,t1 t6;
SELECT * FROM t1 ORDER BY f LIMIT 1;
DROP TABLE t1;
SET sort_buffer_size=DEFAULT;

View File

@ -282,5 +282,19 @@ SELECT 1 FROM
) AS s LIMIT 1; ) AS s LIMIT 1;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Bug #11765023: 57934: DOS POSSIBLE SINCE BINARY CASTING
--echo # DOESN'T ADHERE TO MAX_ALLOWED_PACKET
SET @@GLOBAL.max_allowed_packet=2048;
# reconnect to make the new max packet size take effect
--connect (newconn, localhost, root,,)
SELECT CONVERT('a', BINARY(2049));
SELECT CONVERT('a', CHAR(2049));
connection default;
disconnect newconn;
SET @@GLOBAL.max_allowed_packet=default;
--echo End of 5.1 tests --echo End of 5.1 tests

View File

@ -760,10 +760,56 @@ drop table t1;
--echo # on char > 31 bytes". --echo # on char > 31 bytes".
--echo # --echo #
create table t1(a char(32) not null) engine=myisam; create table t1(a char(32) not null) engine=myisam;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ --error ER_WRONG_ARGUMENTS
--error ER_CANT_CREATE_TABLE
create spatial index i on t1 (a); create spatial index i on t1 (a);
drop table t1; drop table t1;
#
# Bug#11767480 - SPATIAL INDEXES ON NON-SPATIAL COLUMNS CAUSE CRASHES.
#
CREATE TABLE t0 (a BINARY(32) NOT NULL);
--error ER_WRONG_ARGUMENTS
CREATE SPATIAL INDEX i on t0 (a);
INSERT INTO t0 VALUES (1);
--error ER_WRONG_ARGUMENTS
CREATE TABLE t1(
col0 BINARY NOT NULL,
col2 TIMESTAMP,
SPATIAL INDEX i1 (col0)
) ENGINE=MyISAM;
# Test other ways to add indices
CREATE TABLE t1 (
col0 BINARY NOT NULL,
col2 TIMESTAMP
) ENGINE=MyISAM;
--error ER_WRONG_ARGUMENTS
CREATE SPATIAL INDEX idx0 ON t1(col0);
--error ER_WRONG_ARGUMENTS
ALTER TABLE t1 ADD SPATIAL INDEX i1 (col0);
CREATE TABLE t2 (
col0 INTEGER NOT NULL,
col1 POINT,
col2 POINT
);
--error ER_WRONG_ARGUMENTS
CREATE SPATIAL INDEX idx0 ON t2 (col1, col2);
--error ER_WRONG_ARGUMENTS
CREATE TABLE t3 (
col0 INTEGER NOT NULL,
col1 POINT,
col2 LINESTRING,
SPATIAL INDEX i1 (col1, col2)
);
# cleanup
DROP TABLE t0, t1, t2;
--echo End of 5.1 tests --echo End of 5.1 tests

View File

@ -185,6 +185,7 @@ cp Docs/INSTALL-BINARY $DESTDIR/Docs/
cp Docs/manual.chm $DESTDIR/Docs/ || /bin/true cp Docs/manual.chm $DESTDIR/Docs/ || /bin/true
cp ChangeLog $DESTDIR/Docs/ || /bin/true cp ChangeLog $DESTDIR/Docs/ || /bin/true
cp support-files/my-*.ini $DESTDIR/ cp support-files/my-*.ini $DESTDIR/
cp README $DESTDIR/
if [ -f COPYING ] ; then if [ -f COPYING ] ; then
cp COPYING $DESTDIR/ cp COPYING $DESTDIR/

View File

@ -4476,7 +4476,8 @@ int ha_partition::index_read_idx_map(uchar *buf, uint index,
break; break;
} }
} }
m_last_part= part; if (part <= m_part_spec.end_part)
m_last_part= part;
} }
else else
{ {
@ -6396,7 +6397,14 @@ void ha_partition::print_error(int error, myf errflag)
{ {
/* In case m_file has not been initialized, like in bug#42438 */ /* In case m_file has not been initialized, like in bug#42438 */
if (m_file) if (m_file)
{
if (m_last_part >= m_tot_parts)
{
DBUG_ASSERT(0);
m_last_part= 0;
}
m_file[m_last_part]->print_error(error, errflag); m_file[m_last_part]->print_error(error, errflag);
}
else else
handler::print_error(error, errflag); handler::print_error(error, errflag);
} }

View File

@ -2444,6 +2444,19 @@ String *Item_char_typecast::val_str(String *str)
String *res; String *res;
uint32 length; uint32 length;
if (cast_length >= 0 &&
((unsigned) cast_length) > current_thd->variables.max_allowed_packet)
{
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
cast_cs == &my_charset_bin ?
"cast_as_binary" : func_name(),
current_thd->variables.max_allowed_packet);
null_value= 1;
return 0;
}
if (!charset_conversion) if (!charset_conversion)
{ {
if (!(res= args[0]->val_str(str))) if (!(res= args[0]->val_str(str)))

View File

@ -653,6 +653,94 @@ bool init_new_connection_handler_thread()
return 0; return 0;
} }
#ifndef EMBEDDED_LIBRARY
/**
Get a null character terminated string from a user-supplied buffer.
@param buffer[in, out] Pointer to the buffer to be scanned.
@param max_bytes_available[in, out] Limit the bytes to scan.
@param string_length[out] The number of characters scanned not including
the null character.
@remark The string_length does not include the terminating null character.
However, after the call, the buffer is increased by string_length+1
bytes, beyond the null character if there still available bytes to
scan.
@return pointer to beginning of the string scanned.
@retval NULL The buffer content is malformed
*/
static
char *get_null_terminated_string(char **buffer,
size_t *max_bytes_available,
size_t *string_length)
{
char *str= (char *)memchr(*buffer, '\0', *max_bytes_available);
if (str == NULL)
return NULL;
*string_length= (size_t)(str - *buffer);
*max_bytes_available-= *string_length + 1;
str= *buffer;
*buffer += *string_length + 1;
return str;
}
/**
Get a length encoded string from a user-supplied buffer.
@param buffer[in, out] The buffer to scan; updates position after scan.
@param max_bytes_available[in, out] Limit the number of bytes to scan
@param string_length[out] Number of characters scanned
@remark In case the length is zero, then the total size of the string is
considered to be 1 byte; the size byte.
@return pointer to first byte after the header in buffer.
@retval NULL The buffer content is malformed
*/
static
char *get_length_encoded_string(char **buffer,
size_t *max_bytes_available,
size_t *string_length)
{
if (*max_bytes_available == 0)
return NULL;
/* Do double cast to prevent overflow from signed / unsigned conversion */
size_t str_len= (size_t)(unsigned char)**buffer;
/*
If the length encoded string has the length 0
the total size of the string is only one byte long (the size byte)
*/
if (str_len == 0)
{
++*buffer;
*string_length= 0;
/*
Return a pointer to the 0 character so the return value will be
an empty string.
*/
return *buffer-1;
}
if (str_len >= *max_bytes_available)
return NULL;
char *str= *buffer+1;
*string_length= str_len;
*max_bytes_available-= *string_length + 1;
*buffer+= *string_length + 1;
return str;
}
/* /*
Perform handshake, authorize client and update thd ACL variables. Perform handshake, authorize client and update thd ACL variables.
@ -666,7 +754,6 @@ bool init_new_connection_handler_thread()
> 0 error code (not sent to user) > 0 error code (not sent to user)
*/ */
#ifndef EMBEDDED_LIBRARY
static int check_connection(THD *thd) static int check_connection(THD *thd)
{ {
uint connect_errors= 0; uint connect_errors= 0;
@ -855,7 +942,7 @@ static int check_connection(THD *thd)
} }
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
if (end >= (char*) net->read_pos+ pkt_len +2) if (end > (char *)net->read_pos + pkt_len)
{ {
inc_host_errors(&thd->remote.sin_addr); inc_host_errors(&thd->remote.sin_addr);
my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip); my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
@ -867,39 +954,75 @@ static int check_connection(THD *thd)
if ((thd->client_capabilities & CLIENT_TRANSACTIONS) && if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
opt_using_transactions) opt_using_transactions)
net->return_status= &thd->server_status; net->return_status= &thd->server_status;
char *user= end;
char *passwd= strend(user)+1;
uint user_len= passwd - user - 1;
char *db= passwd;
char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
uint dummy_errors;
/* /*
Old clients send null-terminated string as password; new clients send In order to safely scan a head for '\0' string terminators
the size (1 byte) + string (not null-terminated). Hence in case of empty we must keep track of how many bytes remain in the allocated
password both send '\0'. buffer or we might read past the end of the buffer.
This strlen() can't be easily deleted without changing protocol.
Cast *passwd to an unsigned char, so that it doesn't extend the sign for
*passwd > 127 and become 2**32-127+ after casting to uint.
*/ */
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ? size_t bytes_remaining_in_packet= pkt_len - (end - (char *)net->read_pos);
(uchar)(*passwd++) : strlen(passwd);
db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
db + passwd_len + 1 : 0;
/* strlen() can't be easily deleted without changing protocol */
uint db_len= db ? strlen(db) : 0;
if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len) size_t user_len;
char *user= get_null_terminated_string(&end, &bytes_remaining_in_packet,
&user_len);
if (user == NULL)
{ {
inc_host_errors(&thd->remote.sin_addr); inc_host_errors(&thd->remote.sin_addr);
my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip); my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
return 1; return 1;
} }
/*
Old clients send a null-terminated string as password; new clients send
the size (1 byte) + string (not null-terminated). Hence in case of empty
password both send '\0'.
*/
size_t passwd_len= 0;
char *passwd= NULL;
if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
{
/*
4.1+ password. First byte is password length.
*/
passwd= get_length_encoded_string(&end, &bytes_remaining_in_packet,
&passwd_len);
}
else
{
/*
Old passwords are zero terminated strings.
*/
passwd= get_null_terminated_string(&end, &bytes_remaining_in_packet,
&passwd_len);
}
if (passwd == NULL)
{
inc_host_errors(&thd->remote.sin_addr);
my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
return 1;
}
size_t db_len= 0;
char *db= NULL;
if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
{
db= get_null_terminated_string(&end, &bytes_remaining_in_packet,
&db_len);
if (db == NULL)
{
inc_host_errors(&thd->remote.sin_addr);
my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
return 1;
}
}
char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
uint dummy_errors;
/* Since 4.1 all database names are stored in utf8 */ /* Since 4.1 all database names are stored in utf8 */
if (db) if (db)
{ {

View File

@ -1,4 +1,4 @@
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. /* Copyright 2000-2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -11,7 +11,8 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA */
/* drop and alter of tables */ /* drop and alter of tables */
@ -3184,11 +3185,20 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
{ {
column->length*= sql_field->charset->mbmaxlen; column->length*= sql_field->charset->mbmaxlen;
if (key->type == Key::SPATIAL && column->length) if (key->type == Key::SPATIAL)
{ {
my_error(ER_WRONG_SUB_KEY, MYF(0)); if (column->length)
DBUG_RETURN(TRUE); {
} my_error(ER_WRONG_SUB_KEY, MYF(0));
DBUG_RETURN(TRUE);
}
if (!f_is_geom(sql_field->pack_flag))
{
my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX");
DBUG_RETURN(TRUE);
}
}
if (f_is_blob(sql_field->pack_flag) || if (f_is_blob(sql_field->pack_flag) ||
(f_is_geom(sql_field->pack_flag) && key->type != Key::SPATIAL)) (f_is_geom(sql_field->pack_flag) && key->type != Key::SPATIAL))

View File

@ -1113,7 +1113,7 @@ int ha_archive::unpack_row(azio_stream *file_to_read, uchar *record)
ptr+= table->s->null_bytes; ptr+= table->s->null_bytes;
for (Field **field=table->field ; *field ; field++) for (Field **field=table->field ; *field ; field++)
{ {
if (!((*field)->is_null())) if (!((*field)->is_null_in_record(record)))
{ {
ptr= (*field)->unpack(record + (*field)->offset(table->record[0]), ptr); ptr= (*field)->unpack(record + (*field)->offset(table->record[0]), ptr);
} }