mirror of
https://github.com/MariaDB/server.git
synced 2026-04-26 10:15:29 +02:00
merge mysql-5.1-bugteam into mysql-5.1-security
This commit is contained in:
commit
4f738e9b7c
69 changed files with 1267 additions and 698 deletions
|
|
@ -2740,6 +2740,7 @@ public:
|
|||
class Cached_item_str :public Cached_item
|
||||
{
|
||||
Item *item;
|
||||
uint32 value_max_length;
|
||||
String value,tmp_value;
|
||||
public:
|
||||
Cached_item_str(THD *thd, Item *arg);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,9 @@ Cached_item::~Cached_item() {}
|
|||
*/
|
||||
|
||||
Cached_item_str::Cached_item_str(THD *thd, Item *arg)
|
||||
:item(arg), value(min(arg->max_length, thd->variables.max_sort_length))
|
||||
:item(arg),
|
||||
value_max_length(min(arg->max_length, thd->variables.max_sort_length)),
|
||||
value(value_max_length)
|
||||
{}
|
||||
|
||||
bool Cached_item_str::cmp(void)
|
||||
|
|
@ -67,7 +69,7 @@ bool Cached_item_str::cmp(void)
|
|||
bool tmp;
|
||||
|
||||
if ((res=item->val_str(&tmp_value)))
|
||||
res->length(min(res->length(), value.alloced_length()));
|
||||
res->length(min(res->length(), value_max_length));
|
||||
if (null_value != item->null_value)
|
||||
{
|
||||
if ((null_value= item->null_value))
|
||||
|
|
|
|||
|
|
@ -1024,7 +1024,7 @@ bool mysql_opt_change_db(THD *thd,
|
|||
bool force_switch,
|
||||
bool *cur_db_changed);
|
||||
|
||||
void mysql_parse(THD *thd, const char *inBuf, uint length,
|
||||
void mysql_parse(THD *thd, char *rawbuf, uint length,
|
||||
const char ** semicolon);
|
||||
|
||||
bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
|
||||
|
|
|
|||
|
|
@ -534,7 +534,11 @@ void Protocol::end_partial_result_set(THD *thd_arg)
|
|||
bool Protocol::flush()
|
||||
{
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
return net_flush(&thd->net);
|
||||
bool error;
|
||||
thd->main_da.can_overwrite_status= TRUE;
|
||||
error= net_flush(&thd->net);
|
||||
thd->main_da.can_overwrite_status= FALSE;
|
||||
return error;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
|
@ -574,7 +578,8 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
|
|||
if (flags & SEND_NUM_ROWS)
|
||||
{ // Packet with number of elements
|
||||
uchar *pos= net_store_length(buff, list->elements);
|
||||
(void) my_net_write(&thd->net, buff, (size_t) (pos-buff));
|
||||
if (my_net_write(&thd->net, buff, (size_t) (pos-buff)))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
|
|
@ -698,7 +703,7 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
|
|||
if (flags & SEND_DEFAULTS)
|
||||
item->send(&prot, &tmp); // Send default value
|
||||
if (prot.write())
|
||||
break; /* purecov: inspected */
|
||||
DBUG_RETURN(1);
|
||||
#ifndef DBUG_OFF
|
||||
field_types[count++]= field.type;
|
||||
#endif
|
||||
|
|
@ -711,7 +716,9 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
|
|||
to show that there is no cursor.
|
||||
Send no warning information, as it will be sent at statement end.
|
||||
*/
|
||||
write_eof_packet(thd, &thd->net, thd->server_status, thd->total_warn_count);
|
||||
if (write_eof_packet(thd, &thd->net, thd->server_status,
|
||||
thd->total_warn_count))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
DBUG_RETURN(prepare_for_send(list));
|
||||
|
||||
|
|
|
|||
|
|
@ -1653,7 +1653,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
|
|||
|
||||
thd->limit_found_rows = query->found_rows();
|
||||
thd->status_var.last_query_cost= 0.0;
|
||||
thd->main_da.disable_status();
|
||||
if (!thd->main_da.is_set())
|
||||
thd->main_da.disable_status();
|
||||
|
||||
BLOCK_UNLOCK_RD(query_block);
|
||||
DBUG_RETURN(1); // Result sent to client
|
||||
|
|
|
|||
|
|
@ -3391,9 +3391,13 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state)
|
|||
bool xid_cache_insert(XID_STATE *xid_state)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_xid_cache);
|
||||
DBUG_ASSERT(hash_search(&xid_cache, xid_state->xid.key(),
|
||||
xid_state->xid.key_length())==0);
|
||||
my_bool res=my_hash_insert(&xid_cache, (uchar*)xid_state);
|
||||
if (hash_search(&xid_cache, xid_state->xid.key(), xid_state->xid.key_length()))
|
||||
{
|
||||
pthread_mutex_unlock(&LOCK_xid_cache);
|
||||
my_error(ER_XAER_DUPID, MYF(0));
|
||||
return TRUE;
|
||||
}
|
||||
my_bool res= my_hash_insert(&xid_cache, (uchar*)xid_state);
|
||||
pthread_mutex_unlock(&LOCK_xid_cache);
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -658,7 +658,12 @@ void Materialized_cursor::fetch(ulong num_rows)
|
|||
if ((res= table->file->rnd_next(table->record[0])))
|
||||
break;
|
||||
/* Send data only if the read was successful. */
|
||||
result->send_data(item_list);
|
||||
/*
|
||||
If network write failed (i.e. due to a closed socked),
|
||||
the error has already been set. Just return.
|
||||
*/
|
||||
if (result->send_data(item_list))
|
||||
return;
|
||||
}
|
||||
|
||||
switch (res) {
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ st_parsing_options::reset()
|
|||
}
|
||||
|
||||
|
||||
bool Lex_input_stream::init(THD *thd, const char *buff, unsigned int length)
|
||||
bool Lex_input_stream::init(THD *thd, char *buff, unsigned int length)
|
||||
{
|
||||
DBUG_EXECUTE_IF("bug42064_simulate_oom",
|
||||
DBUG_SET("+d,simulate_out_of_memory"););
|
||||
|
|
@ -1292,11 +1292,10 @@ int MYSQLlex(void *arg, void *yythd)
|
|||
ulong version;
|
||||
version=strtol(version_str, NULL, 10);
|
||||
|
||||
/* Accept 'M' 'm' 'm' 'd' 'd' */
|
||||
lip->yySkipn(5);
|
||||
|
||||
if (version <= MYSQL_VERSION_ID)
|
||||
{
|
||||
/* Accept 'M' 'm' 'm' 'd' 'd' */
|
||||
lip->yySkipn(5);
|
||||
/* Expand the content of the special comment as real code */
|
||||
lip->set_echo(TRUE);
|
||||
state=MY_LEX_START;
|
||||
|
|
@ -1304,7 +1303,16 @@ int MYSQLlex(void *arg, void *yythd)
|
|||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Patch and skip the conditional comment to avoid it
|
||||
being propagated infinitely (eg. to a slave).
|
||||
*/
|
||||
char *pcom= lip->yyUnput(' ');
|
||||
comment_closed= ! consume_comment(lip, 1);
|
||||
if (! comment_closed)
|
||||
{
|
||||
*pcom= '!';
|
||||
}
|
||||
/* version allowed to have one level of comment inside. */
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1180,7 +1180,7 @@ public:
|
|||
@retval FALSE OK
|
||||
@retval TRUE Error
|
||||
*/
|
||||
bool init(THD *thd, const char *buff, unsigned int length);
|
||||
bool init(THD *thd, char *buff, unsigned int length);
|
||||
/**
|
||||
Set the echo mode.
|
||||
|
||||
|
|
@ -1294,6 +1294,20 @@ public:
|
|||
m_ptr += n;
|
||||
}
|
||||
|
||||
/**
|
||||
Puts a character back into the stream, canceling
|
||||
the effect of the last yyGet() or yySkip().
|
||||
Note that the echo mode should not change between calls
|
||||
to unput, get, or skip from the stream.
|
||||
*/
|
||||
char *yyUnput(char ch)
|
||||
{
|
||||
*--m_ptr= ch;
|
||||
if (m_echo)
|
||||
m_cpp_ptr--;
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
End of file indicator for the query text to parse.
|
||||
@return true if there are no more characters to parse
|
||||
|
|
@ -1440,7 +1454,7 @@ public:
|
|||
|
||||
private:
|
||||
/** Pointer to the current position in the raw input stream. */
|
||||
const char *m_ptr;
|
||||
char *m_ptr;
|
||||
|
||||
/** Starting position of the last token parsed, in the raw buffer. */
|
||||
const char *m_tok_start;
|
||||
|
|
@ -1972,7 +1986,7 @@ public:
|
|||
@retval FALSE OK
|
||||
@retval TRUE Error
|
||||
*/
|
||||
bool init(THD *thd, const char *buff, unsigned int length)
|
||||
bool init(THD *thd, char *buff, unsigned int length)
|
||||
{
|
||||
return m_lip.init(thd, buff, length);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4735,7 +4735,7 @@ create_sp_error:
|
|||
my_error(ER_XAER_NOTA, MYF(0));
|
||||
break;
|
||||
}
|
||||
thd->transaction.xid_state.xa_state=XA_ACTIVE;
|
||||
thd->transaction.xid_state.xa_state= XA_ACTIVE;
|
||||
my_ok(thd);
|
||||
break;
|
||||
}
|
||||
|
|
@ -4755,16 +4755,16 @@ create_sp_error:
|
|||
my_error(ER_XAER_OUTSIDE, MYF(0));
|
||||
break;
|
||||
}
|
||||
if (xid_cache_search(thd->lex->xid))
|
||||
{
|
||||
my_error(ER_XAER_DUPID, MYF(0));
|
||||
break;
|
||||
}
|
||||
DBUG_ASSERT(thd->transaction.xid_state.xid.is_null());
|
||||
thd->transaction.xid_state.xa_state=XA_ACTIVE;
|
||||
thd->transaction.xid_state.xa_state= XA_ACTIVE;
|
||||
thd->transaction.xid_state.rm_error= 0;
|
||||
thd->transaction.xid_state.xid.set(thd->lex->xid);
|
||||
xid_cache_insert(&thd->transaction.xid_state);
|
||||
if (xid_cache_insert(&thd->transaction.xid_state))
|
||||
{
|
||||
thd->transaction.xid_state.xa_state= XA_NOTR;
|
||||
thd->transaction.xid_state.xid.null();
|
||||
break;
|
||||
}
|
||||
thd->transaction.all.modified_non_trans_table= FALSE;
|
||||
thd->options= ((thd->options & ~(OPTION_KEEP_LOG)) | OPTION_BEGIN);
|
||||
thd->server_status|= SERVER_STATUS_IN_TRANS;
|
||||
|
|
@ -4818,6 +4818,16 @@ create_sp_error:
|
|||
case SQLCOM_XA_COMMIT:
|
||||
if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
|
||||
{
|
||||
/*
|
||||
xid_state.in_thd is always true beside of xa recovery
|
||||
procedure. Note, that there is no race condition here
|
||||
between xid_cache_search and xid_cache_delete, since we're always
|
||||
deleting our own XID (thd->lex->xid == thd->transaction.xid_state.xid).
|
||||
The only case when thd->lex->xid != thd->transaction.xid_state.xid
|
||||
and xid_state->in_thd == 0 is in ha_recover() functionality,
|
||||
which is called before starting client connections, and thus is
|
||||
always single-threaded.
|
||||
*/
|
||||
XID_STATE *xs=xid_cache_search(thd->lex->xid);
|
||||
if (!xs || xs->in_thd)
|
||||
my_error(ER_XAER_NOTA, MYF(0));
|
||||
|
|
@ -5936,13 +5946,13 @@ void mysql_init_multi_delete(LEX *lex)
|
|||
Parse a query.
|
||||
|
||||
@param thd Current thread
|
||||
@param inBuf Begining of the query text
|
||||
@param rawbuf Begining of the query text
|
||||
@param length Length of the query text
|
||||
@param[out] found_semicolon For multi queries, position of the character of
|
||||
the next query in the query text.
|
||||
*/
|
||||
|
||||
void mysql_parse(THD *thd, const char *inBuf, uint length,
|
||||
void mysql_parse(THD *thd, char *rawbuf, uint length,
|
||||
const char ** found_semicolon)
|
||||
{
|
||||
DBUG_ENTER("mysql_parse");
|
||||
|
|
@ -5968,7 +5978,7 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
|
|||
lex_start(thd);
|
||||
mysql_reset_thd_for_next_command(thd);
|
||||
|
||||
if (query_cache_send_result_to_client(thd, (char*) inBuf, length) <= 0)
|
||||
if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0)
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
|
||||
|
|
@ -5977,7 +5987,7 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
|
|||
|
||||
Parser_state parser_state;
|
||||
bool err;
|
||||
if (!(err= parser_state.init(thd, inBuf, length)))
|
||||
if (!(err= parser_state.init(thd, rawbuf, length)))
|
||||
{
|
||||
err= parse_sql(thd, & parser_state, NULL);
|
||||
*found_semicolon= parser_state.m_lip.found_semicolon;
|
||||
|
|
@ -6063,14 +6073,14 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
|
|||
1 can be ignored
|
||||
*/
|
||||
|
||||
bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
|
||||
bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length)
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
bool error= 0;
|
||||
DBUG_ENTER("mysql_test_parse_for_slave");
|
||||
|
||||
Parser_state parser_state;
|
||||
if (!(error= parser_state.init(thd, inBuf, length)))
|
||||
if (!(error= parser_state.init(thd, rawbuf, length)))
|
||||
{
|
||||
lex_start(thd);
|
||||
mysql_reset_thd_for_next_command(thd);
|
||||
|
|
|
|||
|
|
@ -3876,7 +3876,7 @@ void get_partition_set(const TABLE *table, uchar *buf, const uint index,
|
|||
*/
|
||||
|
||||
bool mysql_unpack_partition(THD *thd,
|
||||
const char *part_buf, uint part_info_len,
|
||||
char *part_buf, uint part_info_len,
|
||||
const char *part_state, uint part_state_len,
|
||||
TABLE* table, bool is_create_table_ind,
|
||||
handlerton *default_db_type,
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ void get_full_part_id_from_key(const TABLE *table, uchar *buf,
|
|||
KEY *key_info,
|
||||
const key_range *key_spec,
|
||||
part_id_range *part_spec);
|
||||
bool mysql_unpack_partition(THD *thd, const char *part_buf,
|
||||
bool mysql_unpack_partition(THD *thd, char *part_buf,
|
||||
uint part_info_len,
|
||||
const char *part_state, uint part_state_len,
|
||||
TABLE *table, bool is_create_table_ind,
|
||||
|
|
|
|||
|
|
@ -263,8 +263,11 @@ static bool send_prep_stmt(Prepared_statement *stmt, uint columns)
|
|||
&stmt->lex->param_list,
|
||||
Protocol::SEND_EOF);
|
||||
}
|
||||
/* Flag that a response has already been sent */
|
||||
thd->main_da.disable_status();
|
||||
|
||||
if (!error)
|
||||
/* Flag that a response has already been sent */
|
||||
thd->main_da.disable_status();
|
||||
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
#else
|
||||
|
|
@ -790,7 +793,7 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
|
|||
type (the types are supplied at execute). Check that the
|
||||
supplied type of placeholder can accept a data stream.
|
||||
*/
|
||||
else if (!is_param_long_data_type(param))
|
||||
else if (! is_param_long_data_type(param))
|
||||
DBUG_RETURN(1);
|
||||
res= param->query_val_str(&str);
|
||||
if (param->convert_str_value(thd))
|
||||
|
|
@ -836,7 +839,7 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array,
|
|||
type (the types are supplied at execute). Check that the
|
||||
supplied type of placeholder can accept a data stream.
|
||||
*/
|
||||
else if (is_param_long_data_type(param))
|
||||
else if (! is_param_long_data_type(param))
|
||||
DBUG_RETURN(1);
|
||||
if (param->convert_str_value(stmt->thd))
|
||||
DBUG_RETURN(1); /* out of memory */
|
||||
|
|
|
|||
|
|
@ -356,6 +356,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
|
|||
#ifndef DBUG_OFF
|
||||
int left_events = max_binlog_dump_events;
|
||||
#endif
|
||||
int old_max_allowed_packet= thd->variables.max_allowed_packet;
|
||||
DBUG_ENTER("mysql_binlog_send");
|
||||
DBUG_PRINT("enter",("log_ident: '%s' pos: %ld", log_ident, (long) pos));
|
||||
|
||||
|
|
@ -761,6 +762,7 @@ end:
|
|||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->current_linfo = 0;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
thd->variables.max_allowed_packet= old_max_allowed_packet;
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
err:
|
||||
|
|
@ -778,6 +780,7 @@ err:
|
|||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
if (file >= 0)
|
||||
(void) my_close(file, MYF(MY_WME));
|
||||
thd->variables.max_allowed_packet= old_max_allowed_packet;
|
||||
|
||||
my_message(my_errno, errmsg, MYF(0));
|
||||
DBUG_VOID_RETURN;
|
||||
|
|
@ -1418,6 +1421,7 @@ bool mysql_show_binlog_events(THD* thd)
|
|||
bool ret = TRUE;
|
||||
IO_CACHE log;
|
||||
File file = -1;
|
||||
int old_max_allowed_packet= thd->variables.max_allowed_packet;
|
||||
DBUG_ENTER("mysql_show_binlog_events");
|
||||
|
||||
Log_event::init_show_field_list(&field_list);
|
||||
|
|
@ -1556,6 +1560,7 @@ err:
|
|||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->current_linfo = 0;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
thd->variables.max_allowed_packet= old_max_allowed_packet;
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
|
||||
/* Copyright 2000, 2010 Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
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
|
||||
|
|
@ -9,9 +9,9 @@
|
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
|
||||
/* Function with list databases, tables or fields */
|
||||
|
|
@ -2997,7 +2997,7 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
|
|||
*/
|
||||
if (res == FIND_FILES_DIR)
|
||||
{
|
||||
if (lex->sql_command != SQLCOM_SELECT)
|
||||
if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
|
||||
return 1;
|
||||
thd->clear_error();
|
||||
return 2;
|
||||
|
|
|
|||
|
|
@ -441,7 +441,7 @@ typedef struct st_table_share
|
|||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
/** @todo: Move into *ha_data for partitioning */
|
||||
bool auto_partitioned;
|
||||
const char *partition_info;
|
||||
char *partition_info;
|
||||
uint partition_info_len;
|
||||
uint partition_info_buffer_size;
|
||||
const char *part_state;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue