You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-08 14:02:17 +03:00
Fix for CONC-452 and CONC-453:
Various coverity scan fixes, including CONC-452 and CONC-453. Special thanks to Lukas Javorsky for fixing numerous covscan issues (This patch includes part of his pull request #126). Coverity scan build was using the following cmake parameters: -WITH_EXTERNAL_ZLIB=ON -DWITH_UNIT_TESTS=OFF. CWE-416 (use after free) in dtoa.c (from netlib) is still open.
This commit is contained in:
@@ -49,6 +49,7 @@
|
||||
#include <mariadb_ctype.h>
|
||||
#include "mysql.h"
|
||||
#include <math.h> /* ceil() */
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <malloc.h>
|
||||
@@ -72,6 +73,8 @@
|
||||
#define LONGLONG_MAX ((long long) 0x7FFFFFFFFFFFFFFFLL)
|
||||
#endif
|
||||
|
||||
#define MAX_DBL_STR 3 + DBL_MANT_DIG - DBL_MIN_EXP
|
||||
|
||||
#if defined(HAVE_LONG_LONG) && !defined(ULONGLONG_MAX)
|
||||
/* First check for ANSI C99 definition: */
|
||||
#ifdef ULLONG_MAX
|
||||
@@ -254,19 +257,25 @@ static unsigned long long my_atoull(const char *str, const char *end_str, int *e
|
||||
double my_atod(const char *number, const char *end, int *error)
|
||||
{
|
||||
double val= 0.0;
|
||||
char buffer[255];
|
||||
char buffer[MAX_DBL_STR + 1];
|
||||
int len= (int)(end - number);
|
||||
|
||||
if (len > 254)
|
||||
*error= 1;
|
||||
*error= errno= 0;
|
||||
|
||||
len= MIN(len, 254);
|
||||
memcpy(&buffer, number, len);
|
||||
if (len > MAX_DBL_STR)
|
||||
{
|
||||
*error= 1;
|
||||
len= MAX_DBL_STR;
|
||||
}
|
||||
|
||||
memcpy(buffer, number, len);
|
||||
buffer[len]= '\0';
|
||||
|
||||
val= strtod(buffer, NULL);
|
||||
/* if (!*error)
|
||||
*error= errno; */
|
||||
|
||||
if (errno)
|
||||
*error= errno;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -570,21 +579,26 @@ static void convert_froma_string(MYSQL_BIND *r_param, char *buffer, size_t len)
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
default:
|
||||
{
|
||||
char *start= buffer + r_param->offset; /* stmt_fetch_column sets offset */
|
||||
char *end= buffer + len;
|
||||
size_t copylen= 0;
|
||||
|
||||
if (start < end)
|
||||
if (len > r_param->offset)
|
||||
{
|
||||
copylen= end - start;
|
||||
if (r_param->buffer_length)
|
||||
memcpy(r_param->buffer, start, MIN(copylen, r_param->buffer_length));
|
||||
}
|
||||
if (copylen < r_param->buffer_length)
|
||||
((char *)r_param->buffer)[copylen]= 0;
|
||||
*r_param->error= (copylen > r_param->buffer_length);
|
||||
char *start= buffer + r_param->offset; /* stmt_fetch_column sets offset */
|
||||
char *end= buffer + len;
|
||||
size_t copylen= 0;
|
||||
|
||||
*r_param->length= (ulong)len;
|
||||
if (start < end)
|
||||
{
|
||||
copylen= end - start;
|
||||
if (r_param->buffer_length)
|
||||
memcpy(r_param->buffer, start, MIN(copylen, r_param->buffer_length));
|
||||
}
|
||||
if (copylen < r_param->buffer_length)
|
||||
((char *)r_param->buffer)[copylen]= 0;
|
||||
*r_param->error= (copylen > r_param->buffer_length);
|
||||
|
||||
}
|
||||
else
|
||||
*r_param->error= 1;
|
||||
*r_param->length= (ulong)len;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -657,7 +671,7 @@ static void convert_from_long(MYSQL_BIND *r_param, const MYSQL_FIELD *field, lon
|
||||
if (display_width < r_param->buffer_length)
|
||||
{
|
||||
ma_bmove_upp(buffer + display_width, buffer + len, len);
|
||||
/* coverity [bad_memset] */
|
||||
/* coverity[bad_memset] */
|
||||
memset((void*) buffer, (int) '0', display_width - len);
|
||||
len= display_width;
|
||||
}
|
||||
@@ -880,7 +894,7 @@ static void convert_from_float(MYSQL_BIND *r_param, const MYSQL_FIELD *field, fl
|
||||
if (field->length < length || field->length > MAX_DOUBLE_STRING_REP_LENGTH - 1)
|
||||
break;
|
||||
ma_bmove_upp(buff + field->length, buff + length, length);
|
||||
/* coverity [bad_memset] */
|
||||
/* coverity[bad_memset] */
|
||||
memset((void*) buff, (int) '0', field->length - length);
|
||||
length= field->length;
|
||||
}
|
||||
@@ -1103,74 +1117,68 @@ void ps_fetch_datetime(MYSQL_BIND *r_param, const MYSQL_FIELD * field,
|
||||
unsigned int len= net_field_length(row);
|
||||
|
||||
switch (r_param->buffer_type) {
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
convert_to_datetime(t, row, len, field->type);
|
||||
break;
|
||||
case MYSQL_TYPE_DATE:
|
||||
convert_to_datetime(t, row, len, field->type);
|
||||
break;
|
||||
case MYSQL_TYPE_TIME:
|
||||
convert_to_datetime(t, row, len, field->type);
|
||||
t->year= t->day= t->month= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_YEAR:
|
||||
{
|
||||
MYSQL_TIME tm;
|
||||
convert_to_datetime(&tm, row, len, field->type);
|
||||
shortstore(r_param->buffer, tm.year);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
char dtbuffer[60];
|
||||
MYSQL_TIME tm;
|
||||
size_t length;
|
||||
convert_to_datetime(&tm, row, len, field->type);
|
||||
/*
|
||||
if (tm.time_type== MYSQL_TIMESTAMP_TIME && tm.day)
|
||||
{
|
||||
tm.hour+= tm.day * 24;
|
||||
tm.day=0;
|
||||
}
|
||||
*/
|
||||
switch(field->type) {
|
||||
case MYSQL_TYPE_DATE:
|
||||
length= sprintf(dtbuffer, "%04u-%02u-%02u", tm.year, tm.month, tm.day);
|
||||
break;
|
||||
case MYSQL_TYPE_TIME:
|
||||
length= sprintf(dtbuffer, "%s%02u:%02u:%02u", (tm.neg ? "-" : ""), tm.hour, tm.minute, tm.second);
|
||||
if (field->decimals && field->decimals <= 6)
|
||||
{
|
||||
char ms[8];
|
||||
sprintf(ms, ".%06lu", tm.second_part);
|
||||
if (field->decimals < 6)
|
||||
ms[field->decimals + 1]= 0;
|
||||
length+= strlen(ms);
|
||||
strcat(dtbuffer, ms);
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
length= sprintf(dtbuffer, "%04u-%02u-%02u %02u:%02u:%02u", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second);
|
||||
if (field->decimals && field->decimals <= 6)
|
||||
{
|
||||
char ms[8];
|
||||
sprintf(ms, ".%06lu", tm.second_part);
|
||||
if (field->decimals < 6)
|
||||
ms[field->decimals + 1]= 0;
|
||||
length+= strlen(ms);
|
||||
strcat(dtbuffer, ms);
|
||||
}
|
||||
convert_to_datetime(t, row, len, field->type);
|
||||
break;
|
||||
case MYSQL_TYPE_DATE:
|
||||
convert_to_datetime(t, row, len, field->type);
|
||||
break;
|
||||
case MYSQL_TYPE_TIME:
|
||||
convert_to_datetime(t, row, len, field->type);
|
||||
t->year= t->day= t->month= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_YEAR:
|
||||
{
|
||||
MYSQL_TIME tm;
|
||||
convert_to_datetime(&tm, row, len, field->type);
|
||||
shortstore(r_param->buffer, tm.year);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
char dtbuffer[60];
|
||||
MYSQL_TIME tm;
|
||||
size_t length;
|
||||
convert_to_datetime(&tm, row, len, field->type);
|
||||
|
||||
switch(field->type) {
|
||||
case MYSQL_TYPE_DATE:
|
||||
length= sprintf(dtbuffer, "%04u-%02u-%02u", tm.year, tm.month, tm.day);
|
||||
break;
|
||||
case MYSQL_TYPE_TIME:
|
||||
length= sprintf(dtbuffer, "%s%02u:%02u:%02u", (tm.neg ? "-" : ""), tm.hour, tm.minute, tm.second);
|
||||
if (field->decimals && field->decimals <= 6)
|
||||
{
|
||||
char ms[8];
|
||||
sprintf(ms, ".%06lu", tm.second_part);
|
||||
if (field->decimals < 6)
|
||||
ms[field->decimals + 1]= 0;
|
||||
length+= strlen(ms);
|
||||
strcat(dtbuffer, ms);
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
length= sprintf(dtbuffer, "%04u-%02u-%02u %02u:%02u:%02u", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second);
|
||||
if (field->decimals && field->decimals <= 6)
|
||||
{
|
||||
char ms[8];
|
||||
sprintf(ms, ".%06lu", tm.second_part);
|
||||
if (field->decimals < 6)
|
||||
ms[field->decimals + 1]= 0;
|
||||
length+= strlen(ms);
|
||||
strcat(dtbuffer, ms);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dtbuffer[0]= 0;
|
||||
length= 0;
|
||||
break;
|
||||
}
|
||||
convert_froma_string(r_param, dtbuffer, length);
|
||||
break;
|
||||
default:
|
||||
dtbuffer[0]= 0;
|
||||
length= 0;
|
||||
break;
|
||||
}
|
||||
convert_froma_string(r_param, dtbuffer, length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
(*row) += len;
|
||||
}
|
||||
@@ -1353,3 +1361,4 @@ void mysql_init_ps_subsystem(void)
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
|
||||
|
Reference in New Issue
Block a user