Quick fix: Crash when parsing invalid datetime string #60189

(cherry picked from commit 2b8eb126b4dfaa6b3217adef96dca5ed03708de1)
This commit is contained in:
Oğuzhan Eroğlu 2022-04-15 23:30:34 +03:00 committed by Relintai
parent 8156e2ba36
commit 49a98d13a0

View File

@ -124,50 +124,54 @@ VARIANT_ENUM_CAST(Time::Weekday);
} \ } \
} }
#define PARSE_ISO8601_STRING \ #define PARSE_ISO8601_STRING(ret) \
int64_t year = UNIX_EPOCH_YEAR_AD; \ int64_t year = UNIX_EPOCH_YEAR_AD; \
Month month = MONTH_JANUARY; \ Month month = MONTH_JANUARY; \
uint8_t day = 1; \ uint8_t day = 1; \
uint8_t hour = 0; \ uint8_t hour = 0; \
uint8_t minute = 0; \ uint8_t minute = 0; \
uint8_t second = 0; \ uint8_t second = 0; \
{ \ { \
bool has_date = false, has_time = false; \ bool has_date = false, has_time = false; \
String date, time; \ String date, time; \
if (p_datetime.find_char('T') > 0) { \ if (p_datetime.find_char('T') > 0) { \
has_date = has_time = true; \ has_date = has_time = true; \
Vector<String> array = p_datetime.split("T"); \ Vector<String> array = p_datetime.split("T"); \
date = array[0]; \ ERR_FAIL_COND_V_MSG(array.size() < 2, ret, "Invalid ISO 8601 date/time string."); \
time = array[1]; \ date = array[0]; \
} else if (p_datetime.find_char(' ') > 0) { \ time = array[1]; \
has_date = has_time = true; \ } else if (p_datetime.find_char(' ') > 0) { \
Vector<String> array = p_datetime.split(" "); \ has_date = has_time = true; \
date = array[0]; \ Vector<String> array = p_datetime.split(" "); \
time = array[1]; \ ERR_FAIL_COND_V_MSG(array.size() < 2, ret, "Invalid ISO 8601 date/time string."); \
} else if (p_datetime.find_char('-', 1) > 0) { \ date = array[0]; \
has_date = true; \ time = array[1]; \
date = p_datetime; \ } else if (p_datetime.find_char('-', 1) > 0) { \
} else if (p_datetime.find_char(':') > 0) { \ has_date = true; \
has_time = true; \ date = p_datetime; \
time = p_datetime; \ } else if (p_datetime.find_char(':') > 0) { \
} \ has_time = true; \
/* Set the variables from the contents of the string. */ \ time = p_datetime; \
if (has_date) { \ } \
Vector<int> array = date.split_ints("-", false); \ /* Set the variables from the contents of the string. */ \
year = array[0]; \ if (has_date) { \
month = (Month)array[1]; \ Vector<int> array = date.split_ints("-", false); \
day = array[2]; \ ERR_FAIL_COND_V_MSG(array.size() < 3, ret, "Invalid ISO 8601 date string."); \
/* Handle negative years. */ \ year = array[0]; \
if (p_datetime.find_char('-') == 0) { \ month = (Month)array[1]; \
year *= -1; \ day = array[2]; \
} \ /* Handle negative years. */ \
} \ if (p_datetime.find_char('-') == 0) { \
if (has_time) { \ year *= -1; \
Vector<int> array = time.split_ints(":", false); \ } \
hour = array[0]; \ } \
minute = array[1]; \ if (has_time) { \
second = array[2]; \ Vector<int> array = time.split_ints(":", false); \
} \ ERR_FAIL_COND_V_MSG(array.size() < 3, ret, "Invalid ISO 8601 time string."); \
hour = array[0]; \
minute = array[1]; \
second = array[2]; \
} \
} }
#define EXTRACT_FROM_DICTIONARY \ #define EXTRACT_FROM_DICTIONARY \
@ -253,7 +257,7 @@ String Time::get_time_string_from_unix_time(int64_t p_unix_time_val) const {
} }
Dictionary Time::get_datetime_dict_from_string(String p_datetime, bool p_weekday) const { Dictionary Time::get_datetime_dict_from_string(String p_datetime, bool p_weekday) const {
PARSE_ISO8601_STRING PARSE_ISO8601_STRING(Dictionary())
Dictionary dict; Dictionary dict;
dict[YEAR_KEY] = year; dict[YEAR_KEY] = year;
dict[MONTH_KEY] = (uint8_t)month; dict[MONTH_KEY] = (uint8_t)month;
@ -293,7 +297,7 @@ int64_t Time::get_unix_time_from_datetime_dict(const Dictionary p_datetime) cons
} }
int64_t Time::get_unix_time_from_datetime_string(String p_datetime) const { int64_t Time::get_unix_time_from_datetime_string(String p_datetime) const {
PARSE_ISO8601_STRING PARSE_ISO8601_STRING(-1)
VALIDATE_YMDHMS(0) VALIDATE_YMDHMS(0)
YMD_TO_DAY_NUMBER YMD_TO_DAY_NUMBER
return day_number * SECONDS_PER_DAY + hour * 3600 + minute * 60 + second; return day_number * SECONDS_PER_DAY + hour * 3600 + minute * 60 + second;