diff options
author | Alexander Barkov <bar@mariadb.com> | 2022-11-17 17:51:01 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2022-11-17 17:51:01 +0400 |
commit | 6216a2dfa2faabf8abfd3099a6cd46b00cef4115 (patch) | |
tree | 219818f8934e80d7c7f531bc9391ce3a902a32fe | |
parent | df4c3d96a4aba0e5a9af3bd5158cd2049a978130 (diff) | |
download | mariadb-git-6216a2dfa2faabf8abfd3099a6cd46b00cef4115.tar.gz |
MDEV-29473 UBSAN: Signed integer overflow: X * Y cannot be represented in type 'int' in strings/dtoa.c
Fixing a few problems relealed by UBSAN in type_float.test
- multiplication overflow in dtoa.c
- uninitialized Field::geom_type (and Field::srid as well)
- Wrong call-back function types used in combination with SHOW_FUNC.
Changes in the mysql_show_var_func data type definition were not
properly addressed all around the code by the following commits:
b4ff64568c88ab3ce559e7bd39853d9cbf86704a
18feb62feeb833494d003615861b9c78ec008a90
0ee879ff8ac1b80cd9a963015344f5698a81f309
Adding a helper SHOW_FUNC_ENTRY() function and replacing
all mysql_show_var_func declarations using SHOW_FUNC
to SHOW_FUNC_ENTRY, to catch mysql_show_var_func in the future
at compilation time.
-rw-r--r-- | include/myisampack.h | 2 | ||||
-rw-r--r-- | include/mysql/plugin.h | 12 | ||||
-rw-r--r-- | include/mysql/plugin_audit.h.pp | 10 | ||||
-rw-r--r-- | include/mysql/plugin_auth.h.pp | 10 | ||||
-rw-r--r-- | include/mysql/plugin_encryption.h.pp | 10 | ||||
-rw-r--r-- | include/mysql/plugin_ftparser.h.pp | 10 | ||||
-rw-r--r-- | include/mysql/plugin_password_validation.h.pp | 10 | ||||
-rw-r--r-- | mysql-test/main/type_float.result | 7 | ||||
-rw-r--r-- | mysql-test/main/type_float.test | 10 | ||||
-rw-r--r-- | plugin/handler_socket/handlersocket/handlersocket.cpp | 6 | ||||
-rw-r--r-- | sql/field.cc | 2 | ||||
-rw-r--r-- | sql/log.cc | 2 | ||||
-rw-r--r-- | sql/mysqld.cc | 28 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 6 | ||||
-rw-r--r-- | storage/rocksdb/ha_rocksdb.cc | 21 | ||||
-rw-r--r-- | storage/tokudb/hatoku_hton.cc | 6 | ||||
-rw-r--r-- | strings/dtoa.c | 5 |
17 files changed, 128 insertions, 29 deletions
diff --git a/include/myisampack.h b/include/myisampack.h index 6bfe1958fbc..a7ba32b629c 100644 --- a/include/myisampack.h +++ b/include/myisampack.h @@ -30,7 +30,7 @@ #define mi_uint1korr(A) ((uint8)(*A)) #define mi_sint2korr(A) ((int16) (((int16) (((const uchar*) (A))[1])) |\ - ((int16) ((int16) ((const char*) (A))[0]) << 8))) + ((int16) ((uint16) ((const uchar*) (A))[0]) << 8))) #define mi_sint3korr(A) ((int32) (((((const uchar*) (A))[0]) & 128) ? \ (((uint32) 255L << 24) | \ (((uint32) ((const uchar*) (A))[0]) << 16) |\ diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index 360f633b7dd..b15f42fe6c7 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -200,6 +200,18 @@ struct system_status_var; typedef int (*mysql_show_var_func)(MYSQL_THD, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type); +static inline +struct st_mysql_show_var SHOW_FUNC_ENTRY(const char *name, + mysql_show_var_func func_arg) +{ + struct st_mysql_show_var tmp; + tmp.name= name; + tmp.value= (void*) func_arg; + tmp.type= SHOW_FUNC; + return tmp; +}; + + /* Constants for plugin flags. */ diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 89f7dcc36c4..b8cafee28ec 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -400,6 +400,16 @@ struct st_mysql_show_var { }; struct system_status_var; typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type); +static inline +struct st_mysql_show_var SHOW_FUNC_ENTRY(const char *name, + mysql_show_var_func func_arg) +{ + struct st_mysql_show_var tmp; + tmp.name= name; + tmp.value= (void*) func_arg; + tmp.type= SHOW_FUNC; + return tmp; +}; struct st_mysql_sys_var; struct st_mysql_value; typedef int (*mysql_var_check_func)(void* thd, diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index e515699cad6..68e2bcb9956 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -400,6 +400,16 @@ struct st_mysql_show_var { }; struct system_status_var; typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type); +static inline +struct st_mysql_show_var SHOW_FUNC_ENTRY(const char *name, + mysql_show_var_func func_arg) +{ + struct st_mysql_show_var tmp; + tmp.name= name; + tmp.value= (void*) func_arg; + tmp.type= SHOW_FUNC; + return tmp; +}; struct st_mysql_sys_var; struct st_mysql_value; typedef int (*mysql_var_check_func)(void* thd, diff --git a/include/mysql/plugin_encryption.h.pp b/include/mysql/plugin_encryption.h.pp index 7defe0aec2c..838d0e49ed5 100644 --- a/include/mysql/plugin_encryption.h.pp +++ b/include/mysql/plugin_encryption.h.pp @@ -400,6 +400,16 @@ struct st_mysql_show_var { }; struct system_status_var; typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type); +static inline +struct st_mysql_show_var SHOW_FUNC_ENTRY(const char *name, + mysql_show_var_func func_arg) +{ + struct st_mysql_show_var tmp; + tmp.name= name; + tmp.value= (void*) func_arg; + tmp.type= SHOW_FUNC; + return tmp; +}; struct st_mysql_sys_var; struct st_mysql_value; typedef int (*mysql_var_check_func)(void* thd, diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index a36f51e74e1..3c28bd3b2e0 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -400,6 +400,16 @@ struct st_mysql_show_var { }; struct system_status_var; typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type); +static inline +struct st_mysql_show_var SHOW_FUNC_ENTRY(const char *name, + mysql_show_var_func func_arg) +{ + struct st_mysql_show_var tmp; + tmp.name= name; + tmp.value= (void*) func_arg; + tmp.type= SHOW_FUNC; + return tmp; +}; struct st_mysql_sys_var; struct st_mysql_value; typedef int (*mysql_var_check_func)(void* thd, diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp index 9701ad1b92f..bf05ca36351 100644 --- a/include/mysql/plugin_password_validation.h.pp +++ b/include/mysql/plugin_password_validation.h.pp @@ -400,6 +400,16 @@ struct st_mysql_show_var { }; struct system_status_var; typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type); +static inline +struct st_mysql_show_var SHOW_FUNC_ENTRY(const char *name, + mysql_show_var_func func_arg) +{ + struct st_mysql_show_var tmp; + tmp.name= name; + tmp.value= (void*) func_arg; + tmp.type= SHOW_FUNC; + return tmp; +}; struct st_mysql_sys_var; struct st_mysql_value; typedef int (*mysql_var_check_func)(void* thd, diff --git a/mysql-test/main/type_float.result b/mysql-test/main/type_float.result index a5f70d9ef80..5354fa50e19 100644 --- a/mysql-test/main/type_float.result +++ b/mysql-test/main/type_float.result @@ -964,5 +964,12 @@ id a DELETE FROM t1 WHERE a=CAST(0.671437 AS FLOAT); DROP TABLE t1; # +# MDEV-29473 UBSAN: Signed integer overflow: X * Y cannot be represented in type 'int' in strings/dtoa.c +# +CREATE TABLE t1 (c DOUBLE); +INSERT INTO t1 VALUES ('1e4294967297'); +ERROR 22003: Out of range value for column 'c' at row 1 +DROP TABLE t1; +# # End of 10.3 tests # diff --git a/mysql-test/main/type_float.test b/mysql-test/main/type_float.test index 5d7f7de7d0b..3f9781e6224 100644 --- a/mysql-test/main/type_float.test +++ b/mysql-test/main/type_float.test @@ -670,6 +670,16 @@ SELECT * FROM t1; DELETE FROM t1 WHERE a=CAST(0.671437 AS FLOAT); DROP TABLE t1; +--echo # +--echo # MDEV-29473 UBSAN: Signed integer overflow: X * Y cannot be represented in type 'int' in strings/dtoa.c +--echo # + +# This test was failing with UBSAN builds + +CREATE TABLE t1 (c DOUBLE); +--error ER_WARN_DATA_OUT_OF_RANGE +INSERT INTO t1 VALUES ('1e4294967297'); +DROP TABLE t1; --echo # --echo # End of 10.3 tests diff --git a/plugin/handler_socket/handlersocket/handlersocket.cpp b/plugin/handler_socket/handlersocket/handlersocket.cpp index 8133497044c..45c9e13b2ca 100644 --- a/plugin/handler_socket/handlersocket/handlersocket.cpp +++ b/plugin/handler_socket/handlersocket/handlersocket.cpp @@ -185,7 +185,9 @@ static SHOW_VAR hs_status_variables[] = { {NullS, NullS, SHOW_LONG} }; -static int show_hs_vars(THD *thd, SHOW_VAR *var, char *buff) +static int show_hs_vars(THD *thd, SHOW_VAR *var, void *buff, + struct system_status_var *status_var, + enum enum_var_type var_type) { var->type= SHOW_ARRAY; var->value= (char *) &hs_status_variables; @@ -193,7 +195,7 @@ static int show_hs_vars(THD *thd, SHOW_VAR *var, char *buff) } static SHOW_VAR daemon_handlersocket_status_variables[] = { - {"Hs", (char*) show_hs_vars, SHOW_FUNC}, + SHOW_FUNC_ENTRY("Hs", &show_hs_vars), {NullS, NullS, SHOW_LONG} }; diff --git a/sql/field.cc b/sql/field.cc index f430e6209d5..43514347106 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -11073,6 +11073,8 @@ bool Field_vers_trx_id::test_if_equality_guarantees_uniqueness(const Item* item) Column_definition::Column_definition(THD *thd, Field *old_field, Field *orig_field) { + geom_type= Field::GEOM_GEOMETRY; + srid= 0; on_update= NULL; field_name= old_field->field_name; length= old_field->field_length; diff --git a/sql/log.cc b/sql/log.cc index 7ca9b38dc6e..4b071f133f7 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -10501,7 +10501,7 @@ static int show_binlog_vars(THD *thd, SHOW_VAR *var, void *, } static SHOW_VAR binlog_status_vars_top[]= { - {"Binlog", (char *) &show_binlog_vars, SHOW_FUNC}, + SHOW_FUNC_ENTRY("Binlog", &show_binlog_vars), {NullS, NullS, SHOW_LONG} }; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 84c3b9fb0a6..d58f2ed557f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8395,7 +8395,9 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff, rpl_semi_sync_master_show_##name #define DEF_SHOW_FUNC(name, show_type) \ - static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR *var, char *buff) \ + static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR *var, void *buff, \ + system_status_var *status_var, \ + enum_var_type var_type) \ { \ repl_semisync_master.set_export_stats(); \ var->type= show_type; \ @@ -8661,7 +8663,7 @@ SHOW_VAR status_vars[]= { {"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG}, {"Created_tmp_tables", (char*) offsetof(STATUS_VAR, created_tmp_tables_), SHOW_LONG_STATUS}, #ifndef DBUG_OFF - {"Debug", (char*) &debug_status_func, SHOW_FUNC}, + SHOW_FUNC_ENTRY("Debug", &debug_status_func), #endif {"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG}, {"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH}, @@ -8713,7 +8715,7 @@ SHOW_VAR status_vars[]= { {"Handler_tmp_write", (char*) offsetof(STATUS_VAR, ha_tmp_write_count), SHOW_LONG_STATUS}, {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS}, {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS}, - {"Key", (char*) &show_default_keycache, SHOW_FUNC}, + SHOW_FUNC_ENTRY("Key", &show_default_keycache), {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS}, {"Max_statement_time_exceeded", (char*) offsetof(STATUS_VAR, max_statement_time_exceeded), SHOW_LONG_STATUS}, {"Master_gtid_wait_count", (char*) offsetof(STATUS_VAR, master_gtid_wait_count), SHOW_LONG_STATUS}, @@ -8737,20 +8739,20 @@ SHOW_VAR status_vars[]= { {"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS}, {"Rows_tmp_read", (char*) offsetof(STATUS_VAR, rows_tmp_read), SHOW_LONGLONG_STATUS}, #ifdef HAVE_REPLICATION - {"Rpl_semi_sync_master_status", (char*) &SHOW_FNAME(status), SHOW_FUNC}, - {"Rpl_semi_sync_master_clients", (char*) &SHOW_FNAME(clients), SHOW_FUNC}, + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_status", &SHOW_FNAME(status)), + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_clients", &SHOW_FNAME(clients)), {"Rpl_semi_sync_master_yes_tx", (char*) &rpl_semi_sync_master_yes_transactions, SHOW_LONG}, {"Rpl_semi_sync_master_no_tx", (char*) &rpl_semi_sync_master_no_transactions, SHOW_LONG}, - {"Rpl_semi_sync_master_wait_sessions", (char*) &SHOW_FNAME(wait_sessions), SHOW_FUNC}, + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_wait_sessions", &SHOW_FNAME(wait_sessions)), {"Rpl_semi_sync_master_no_times", (char*) &rpl_semi_sync_master_off_times, SHOW_LONG}, {"Rpl_semi_sync_master_timefunc_failures", (char*) &rpl_semi_sync_master_timefunc_fails, SHOW_LONG}, {"Rpl_semi_sync_master_wait_pos_backtraverse", (char*) &rpl_semi_sync_master_wait_pos_backtraverse, SHOW_LONG}, - {"Rpl_semi_sync_master_tx_wait_time", (char*) &SHOW_FNAME(trx_wait_time), SHOW_FUNC}, - {"Rpl_semi_sync_master_tx_waits", (char*) &SHOW_FNAME(trx_wait_num), SHOW_FUNC}, - {"Rpl_semi_sync_master_tx_avg_wait_time", (char*) &SHOW_FNAME(avg_trx_wait_time), SHOW_FUNC}, - {"Rpl_semi_sync_master_net_wait_time", (char*) &SHOW_FNAME(net_wait_time), SHOW_FUNC}, - {"Rpl_semi_sync_master_net_waits", (char*) &SHOW_FNAME(net_wait_num), SHOW_FUNC}, - {"Rpl_semi_sync_master_net_avg_wait_time", (char*) &SHOW_FNAME(avg_net_wait_time), SHOW_FUNC}, + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_tx_wait_time", &SHOW_FNAME(trx_wait_time)), + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_tx_waits", &SHOW_FNAME(trx_wait_num)), + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_tx_avg_wait_time", &SHOW_FNAME(avg_trx_wait_time)), + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_net_wait_time", &SHOW_FNAME(net_wait_time)), + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_net_waits", &SHOW_FNAME(net_wait_num)), + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_net_avg_wait_time", &SHOW_FNAME(avg_net_wait_time)), {"Rpl_semi_sync_master_request_ack", (char*) &rpl_semi_sync_master_request_ack, SHOW_LONGLONG}, {"Rpl_semi_sync_master_get_ack", (char*)&rpl_semi_sync_master_get_ack, SHOW_LONGLONG}, {"Rpl_semi_sync_slave_status", (char*) &rpl_semi_sync_slave_status, SHOW_BOOL}, @@ -8858,7 +8860,7 @@ SHOW_VAR status_vars[]= { {"Uptime_since_flush_status",(char*) &show_flushstatustime, SHOW_SIMPLE_FUNC}, #endif #ifdef WITH_WSREP - {"wsrep", (char*) &wsrep_show_status, SHOW_FUNC}, + SHOW_FUNC_ENTRY("wsrep", &wsrep_show_status), #endif {NullS, NullS, SHOW_LONG} }; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index cd2d36df112..81236343642 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -18415,7 +18415,9 @@ innodb_enable_monitor_at_startup( /****************************************************************//** Callback function for accessing the InnoDB variables from MySQL: SHOW VARIABLES. */ -static int show_innodb_vars(THD*, SHOW_VAR* var, char*) +static int show_innodb_vars(THD*, SHOW_VAR* var, void *, + struct system_status_var *status_var, + enum enum_var_type var_type) { innodb_export_status(); var->type = SHOW_ARRAY; @@ -18861,7 +18863,7 @@ innobase_debug_sync_set(THD *thd, st_mysql_sys_var*, void *, const void *value) #endif static SHOW_VAR innodb_status_variables_export[]= { - {"Innodb", (char*) &show_innodb_vars, SHOW_FUNC}, + SHOW_FUNC_ENTRY("Innodb", &show_innodb_vars), {NullS, NullS, SHOW_LONG} }; diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index cd366a12462..aa934695322 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -13102,7 +13102,9 @@ bool ha_rocksdb::commit_inplace_alter_table( #define SHOW_FNAME(name) rocksdb_show_##name #define DEF_SHOW_FUNC(name, key) \ - static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR * var, char *buff) { \ + static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR * var, void *buff, \ + struct system_status_var *status_var, \ + enum enum_var_type var_type) { \ rocksdb_status_counters.name = \ rocksdb_stats->getTickerCount(rocksdb::key); \ var->type = SHOW_LONGLONG; \ @@ -13111,7 +13113,7 @@ bool ha_rocksdb::commit_inplace_alter_table( } #define DEF_STATUS_VAR(name) \ - { "rocksdb_" #name, (char *)&SHOW_FNAME(name), SHOW_FUNC } + SHOW_FUNC_ENTRY( "rocksdb_" #name, &SHOW_FNAME(name)) #define DEF_STATUS_VAR_PTR(name, ptr, option) \ { "rocksdb_" name, (char *)ptr, option } @@ -13339,11 +13341,14 @@ static SHOW_VAR myrocks_status_variables[] = { {NullS, NullS, SHOW_LONG}}; -static void show_myrocks_vars(THD *thd, SHOW_VAR *var, char *buff) { +static int show_myrocks_vars(THD *thd, SHOW_VAR *var, void *buff, + struct system_status_var *, + enum enum_var_type) { myrocks_update_status(); myrocks_update_memory_status(); var->type = SHOW_ARRAY; var->value = reinterpret_cast<char *>(&myrocks_status_variables); + return 0; } static ulonglong io_stall_prop_value( @@ -13424,10 +13429,13 @@ static SHOW_VAR rocksdb_stall_status_variables[] = { // end of the array marker {NullS, NullS, SHOW_LONG}}; -static void show_rocksdb_stall_vars(THD *thd, SHOW_VAR *var, char *buff) { +static int show_rocksdb_stall_vars(THD *thd, SHOW_VAR *var, void *buff, + struct system_status_var *, + enum enum_var_type) { update_rocksdb_stall_status(); var->type = SHOW_ARRAY; var->value = reinterpret_cast<char *>(&rocksdb_stall_status_variables); + return 0; } static SHOW_VAR rocksdb_status_vars[] = { @@ -13532,9 +13540,8 @@ static SHOW_VAR rocksdb_status_vars[] = { // the variables generated by SHOW_FUNC are sorted only by prefix (first // arg in the tuple below), so make sure it is unique to make sorting // deterministic as quick sort is not stable - {"rocksdb", reinterpret_cast<char *>(&show_myrocks_vars), SHOW_FUNC}, - {"rocksdb_stall", reinterpret_cast<char *>(&show_rocksdb_stall_vars), - SHOW_FUNC}, + SHOW_FUNC_ENTRY("rocksdb", &show_myrocks_vars), + SHOW_FUNC_ENTRY("rocksdb_stall", &show_rocksdb_stall_vars), {NullS, NullS, SHOW_LONG}}; /* diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc index 81355ea20ff..79ca28188ac 100644 --- a/storage/tokudb/hatoku_hton.cc +++ b/storage/tokudb/hatoku_hton.cc @@ -1894,7 +1894,9 @@ static void tokudb_lock_wait_needed_callback( // and prefixed with "TOKUDB_" static int show_tokudb_vars(TOKUDB_UNUSED(THD* thd), SHOW_VAR* var, - TOKUDB_UNUSED(char* buff)) { + TOKUDB_UNUSED(void* buff), + TOKUDB_UNUSED(system_status_var *status_var), + TOKUDB_UNUSED(enum_var_type var_type)) { TOKUDB_DBUG_ENTER(""); int error; @@ -1994,7 +1996,7 @@ static int show_tokudb_vars(TOKUDB_UNUSED(THD* thd), } static SHOW_VAR toku_global_status_variables_export[]= { - {"Tokudb", (char*)&show_tokudb_vars, SHOW_FUNC}, + SHOW_FUNC_ENTRY("Tokudb", &show_tokudb_vars), {NullS, NullS, SHOW_LONG} }; diff --git a/strings/dtoa.c b/strings/dtoa.c index e31b7e92d7c..13e28821f69 100644 --- a/strings/dtoa.c +++ b/strings/dtoa.c @@ -1478,7 +1478,10 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s L= c - '0'; s1= s; while (++s < end && (c= *s) >= '0' && c <= '9') - L= 10*L + c - '0'; + { + if (L < 19999) + L= 10*L + c - '0'; + } if (s - s1 > 8 || L > 19999) /* Avoid confusion from exponents * so large that e might overflow. |