You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-30 19:23:07 +03:00
MCOL-1647 Fix TIME regressions
Fixes the following: * Read past buffer end in intToDatetime / intToTime * Allow intToTime to convert datetime * Allow intToTime to convert shortened time values * Allow stringToTime to convert datetime and int time values * Fix saturation / bad values in intToTime and stringToTime * Fix TIME return in STR_TO_DATE() * Fix NULL return on type inequality for TIMEDIFF() * Fix zero day calculation error in ADDTIME()/SUBTIME() * Fix DATETIME to int calculation error in aggregate bit operations * Make the new harderning flags optional with -DSECURITY_HARDENED_NEW
This commit is contained in:
@ -2566,7 +2566,6 @@ int64_t DataConvert::intToDatetime(int64_t data, bool* date)
|
||||
hour = string(buf + 8, 2);
|
||||
min = string(buf + 10, 2);
|
||||
sec = string(buf + 12, 2);
|
||||
msec = string(buf + 14, 6);
|
||||
break;
|
||||
|
||||
case 12:
|
||||
@ -2576,7 +2575,6 @@ int64_t DataConvert::intToDatetime(int64_t data, bool* date)
|
||||
hour = string(buf + 6, 2);
|
||||
min = string(buf + 8, 2);
|
||||
sec = string(buf + 10, 2);
|
||||
msec = string(buf + 12, 6);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
@ -2585,7 +2583,6 @@ int64_t DataConvert::intToDatetime(int64_t data, bool* date)
|
||||
hour = string(buf + 4, 2);
|
||||
min = string(buf + 6, 2);
|
||||
sec = string(buf + 8, 2);
|
||||
msec = string(buf + 10, 6);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
@ -2594,7 +2591,6 @@ int64_t DataConvert::intToDatetime(int64_t data, bool* date)
|
||||
hour = string(buf + 3, 2);
|
||||
min = string(buf + 5, 2);
|
||||
sec = string(buf + 7, 2);
|
||||
msec = string(buf + 9, 6);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
@ -2645,7 +2641,7 @@ int64_t DataConvert::intToDatetime(int64_t data, bool* date)
|
||||
h = atoi(hour.c_str());
|
||||
minute = atoi(min.c_str());
|
||||
s = atoi(sec.c_str());
|
||||
ms = atoi(msec.c_str());
|
||||
ms = 0;
|
||||
|
||||
if (!isDateValid(d, m, y) || !isDateTimeValid(h, minute, s, ms))
|
||||
return -1;
|
||||
@ -2664,7 +2660,7 @@ int64_t DataConvert::intToDatetime(int64_t data, bool* date)
|
||||
return *(reinterpret_cast<uint64_t*>(&adaytime));
|
||||
}
|
||||
|
||||
int64_t DataConvert::intToTime(int64_t data)
|
||||
int64_t DataConvert::intToTime(int64_t data, bool fromString)
|
||||
{
|
||||
char buf[21] = {0};
|
||||
char* bufread = buf;
|
||||
@ -2693,43 +2689,78 @@ int64_t DataConvert::intToTime(int64_t data)
|
||||
bufread++;
|
||||
}
|
||||
|
||||
bool zero = false;
|
||||
|
||||
switch (strlen(bufread))
|
||||
{
|
||||
// A full datetime
|
||||
case 14:
|
||||
hour = string(buf + 8, 2);
|
||||
min = string(buf + 10, 2);
|
||||
sec = string(buf + 12, 2);
|
||||
break;
|
||||
|
||||
// Date so this is all 0
|
||||
case 8:
|
||||
zero = true;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
hour = string(bufread, 3);
|
||||
min = string(bufread + 2, 2);
|
||||
sec = string(bufread + 4, 2);
|
||||
msec = string(bufread + 6, 6);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
hour = string(bufread, 2);
|
||||
min = string(bufread + 2, 2);
|
||||
sec = string(bufread + 4, 2);
|
||||
msec = string(bufread + 6, 6);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
hour = string(bufread, 1);
|
||||
min = string(bufread + 1, 2);
|
||||
sec = string(bufread + 3, 2);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
min = string(bufread, 2);
|
||||
sec = string(bufread + 2, 2);
|
||||
msec = string(bufread + 4, 6);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
min = string(bufread, 1);
|
||||
sec = string(bufread + 1, 2);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
sec = string(bufread, 2);
|
||||
msec = string(bufread + 2, 6);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
sec = string(bufread, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
h = atoi(hour.c_str());
|
||||
minute = atoi(min.c_str());
|
||||
s = atoi(sec.c_str());
|
||||
ms = atoi(msec.c_str());
|
||||
if (!zero)
|
||||
{
|
||||
h = atoi(hour.c_str());
|
||||
minute = atoi(min.c_str());
|
||||
s = atoi(sec.c_str());
|
||||
}
|
||||
else if (fromString)
|
||||
{
|
||||
// Saturate fromString
|
||||
h = 838;
|
||||
minute = 59;
|
||||
s = 59;
|
||||
ms = 999999;
|
||||
}
|
||||
|
||||
if (!isTimeValid(h, minute, s, ms))
|
||||
if (!isTimeValid(h, minute, s, 0))
|
||||
return -1;
|
||||
|
||||
atime.hour = h;
|
||||
@ -2749,6 +2780,7 @@ int64_t DataConvert::stringToTime(const string& data)
|
||||
uint64_t min = 0, sec = 0, msec = 0;
|
||||
int64_t day = -1, hour = 0;
|
||||
bool isNeg = false;
|
||||
bool hasDate = false;
|
||||
string time, hms, ms;
|
||||
char* end = NULL;
|
||||
|
||||
@ -2760,18 +2792,27 @@ int64_t DataConvert::stringToTime(const string& data)
|
||||
isNeg = true;
|
||||
}
|
||||
|
||||
if (data.substr(pos+1, data.length()-pos-1).find("-") != string::npos)
|
||||
{
|
||||
// A second dash, this has a date
|
||||
hasDate = true;
|
||||
isNeg = false;
|
||||
}
|
||||
// Day
|
||||
pos = data.find(" ");
|
||||
|
||||
if (pos != string::npos)
|
||||
{
|
||||
day = strtol(data.substr(0, pos).c_str(), &end, 10);
|
||||
if (!hasDate)
|
||||
{
|
||||
day = strtol(data.substr(0, pos).c_str(), &end, 10);
|
||||
|
||||
if (*end != '\0')
|
||||
return -1;
|
||||
if (*end != '\0')
|
||||
return -1;
|
||||
|
||||
hour = day * 24;
|
||||
day = -1;
|
||||
hour = day * 24;
|
||||
day = -1;
|
||||
}
|
||||
time = data.substr(pos + 1, data.length() - pos - 1);
|
||||
}
|
||||
else
|
||||
@ -2779,6 +2820,22 @@ int64_t DataConvert::stringToTime(const string& data)
|
||||
time = data;
|
||||
}
|
||||
|
||||
if (time.find(":") == string::npos)
|
||||
{
|
||||
if (hasDate)
|
||||
{
|
||||
// Has dashes, no colons. This is just a date!
|
||||
// Or the length < 6 (MariaDB returns NULL)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is an int time
|
||||
return intToTime(atoll(time.c_str()), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Fraction
|
||||
pos = time.find(".");
|
||||
|
||||
@ -2797,11 +2854,18 @@ int64_t DataConvert::stringToTime(const string& data)
|
||||
|
||||
if (pos == string::npos)
|
||||
{
|
||||
hour += atoi(hms.c_str());
|
||||
if (hour >= 0)
|
||||
hour += atoi(hms.c_str());
|
||||
else
|
||||
hour -= atoi(hms.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
hour += atoi(hms.substr(0, pos).c_str());
|
||||
if (hour >= 0)
|
||||
hour += atoi(hms.substr(0, pos).c_str());
|
||||
else
|
||||
hour -= atoi(hms.substr(0, pos).c_str());
|
||||
|
||||
ms = hms.substr(pos + 1, hms.length() - pos - 1);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user