MXS-1703 Better strtoll() & strtoull() error detection
The functions do not set errno on all invalid input, so it's best to check endptr. Also, strtoll is now used for server id scanning through QueryResult.
This commit is contained in:
parent
ca9682f042
commit
7f36339f53
@ -155,8 +155,9 @@ Gtid Gtid::from_string(const char* str, char** endptr)
|
||||
{
|
||||
errno = 0;
|
||||
parsed_numbers[i] = strtoull(ptr, &strtoull_endptr, 10);
|
||||
// No parse error
|
||||
if (errno != 0)
|
||||
// Check for parse error. Even this is not quite enough because strtoull will silently convert
|
||||
// negative values. Yet, strtoull is required for the third value.
|
||||
if (errno != 0 || strtoull_endptr == ptr)
|
||||
{
|
||||
error = true;
|
||||
}
|
||||
|
@ -179,7 +179,11 @@ bool MariaDBServer::do_show_slave_status()
|
||||
server_version != MYSQL_SERVER_VERSION_51)
|
||||
{
|
||||
/* Get Master_Server_Id */
|
||||
master_server_id = scan_server_id(result->get_string(i_master_server_id).c_str());
|
||||
auto parsed = result->get_uint(i_master_server_id);
|
||||
if (parsed >= 0)
|
||||
{
|
||||
master_server_id = parsed;
|
||||
}
|
||||
}
|
||||
|
||||
if (server_version == MYSQL_SERVER_VERSION_100)
|
||||
|
@ -13,8 +13,6 @@
|
||||
|
||||
#include "utilities.hh"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <maxscale/debug.h>
|
||||
|
||||
@ -23,22 +21,6 @@ using std::string;
|
||||
/** Server id default value */
|
||||
const int64_t SERVER_ID_UNKNOWN = -1;
|
||||
|
||||
int64_t scan_server_id(const char* id_string)
|
||||
{
|
||||
int64_t server_id = SERVER_ID_UNKNOWN;
|
||||
ss_debug(int rv = ) sscanf(id_string, "%" PRId64, &server_id);
|
||||
ss_dassert(rv == 1);
|
||||
// Server id can be 0, which was even the default value until 10.2.1.
|
||||
// KB is a bit hazy on this, but apparently when replicating, the server id should not be 0. Not sure,
|
||||
// so MaxScale allows this.
|
||||
#if defined(SS_DEBUG)
|
||||
const int64_t SERVER_ID_MIN = std::numeric_limits<uint32_t>::min();
|
||||
const int64_t SERVER_ID_MAX = std::numeric_limits<uint32_t>::max();
|
||||
#endif
|
||||
ss_dassert(server_id >= SERVER_ID_MIN && server_id <= SERVER_ID_MAX);
|
||||
return server_id;
|
||||
}
|
||||
|
||||
QueryResult::QueryResult(MYSQL_RES* resultset)
|
||||
: m_resultset(resultset)
|
||||
, m_columns(-1)
|
||||
@ -107,11 +89,12 @@ int64_t QueryResult::get_uint(int64_t column_ind) const
|
||||
ss_dassert(column_ind < m_columns);
|
||||
char* data = m_rowdata[column_ind];
|
||||
int64_t rval = -1;
|
||||
if (data)
|
||||
if (data && *data)
|
||||
{
|
||||
errno = 0; // strtoll sets this
|
||||
auto parsed = strtoll(data, NULL, 10);
|
||||
if (parsed >= 0 && errno == 0)
|
||||
char* endptr = NULL;
|
||||
auto parsed = strtoll(data, &endptr, 10);
|
||||
if (parsed >= 0 && errno == 0 && *endptr == '\0')
|
||||
{
|
||||
rval = parsed;
|
||||
}
|
||||
|
@ -31,14 +31,6 @@
|
||||
|
||||
extern const int64_t SERVER_ID_UNKNOWN;
|
||||
|
||||
/**
|
||||
* Scan a server id from a string.
|
||||
*
|
||||
* @param id_string
|
||||
* @return Server id, or -1 if scanning fails
|
||||
*/
|
||||
int64_t scan_server_id(const char* id_string);
|
||||
|
||||
/**
|
||||
* Helper class for simplifying working with resultsets. Used in MariaDBServer.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user