Proper validation of negative values in datetime strings and datetime dicts

(cherry picked from commit cf9fc0b936)
This commit is contained in:
laws65 2022-04-17 19:11:45 +09:30 committed by Rémi Verschelde
parent fd329d19e8
commit 6aac042faa
2 changed files with 16 additions and 11 deletions

View file

@ -97,12 +97,17 @@ VARIANT_ENUM_CAST(Time::Weekday);
#define VALIDATE_YMDHMS(ret) \ #define VALIDATE_YMDHMS(ret) \
ERR_FAIL_COND_V_MSG(month == 0, ret, "Invalid month value of: " + itos(month) + ", months are 1-indexed and cannot be 0. See the Time.Month enum for valid values."); \ ERR_FAIL_COND_V_MSG(month == 0, ret, "Invalid month value of: " + itos(month) + ", months are 1-indexed and cannot be 0. See the Time.Month enum for valid values."); \
ERR_FAIL_COND_V_MSG(month < 0, ret, "Invalid month value of: " + itos(month) + "."); \
ERR_FAIL_COND_V_MSG(month > 12, ret, "Invalid month value of: " + itos(month) + ". See the Time.Month enum for valid values."); \ ERR_FAIL_COND_V_MSG(month > 12, ret, "Invalid month value of: " + itos(month) + ". See the Time.Month enum for valid values."); \
ERR_FAIL_COND_V_MSG(hour > 23, ret, "Invalid hour value of: " + itos(hour) + "."); \ ERR_FAIL_COND_V_MSG(hour > 23, ret, "Invalid hour value of: " + itos(hour) + "."); \
ERR_FAIL_COND_V_MSG(hour < 0, ret, "Invalid hour value of: " + itos(hour) + "."); \
ERR_FAIL_COND_V_MSG(minute > 59, ret, "Invalid minute value of: " + itos(minute) + "."); \ ERR_FAIL_COND_V_MSG(minute > 59, ret, "Invalid minute value of: " + itos(minute) + "."); \
ERR_FAIL_COND_V_MSG(minute < 0, ret, "Invalid minute value of: " + itos(minute) + "."); \
ERR_FAIL_COND_V_MSG(second > 59, ret, "Invalid second value of: " + itos(second) + " (leap seconds are not supported)."); \ ERR_FAIL_COND_V_MSG(second > 59, ret, "Invalid second value of: " + itos(second) + " (leap seconds are not supported)."); \
ERR_FAIL_COND_V_MSG(second < 0, ret, "Invalid second value of: " + itos(second) + "."); \
ERR_FAIL_COND_V_MSG(day == 0, ret, "Invalid day value of: " + itos(day) + ", days are 1-indexed and cannot be 0."); \
ERR_FAIL_COND_V_MSG(day < 0, ret, "Invalid day value of: " + itos(day) + "."); \
/* Do this check after month is tested as valid. */ \ /* Do this check after month is tested as valid. */ \
ERR_FAIL_COND_V_MSG(day == 0, ret, "Invalid day value of: " + itos(month) + ", days are 1-indexed and cannot be 0."); \
uint8_t days_in_this_month = MONTH_DAYS_TABLE[IS_LEAP_YEAR(year)][month - 1]; \ uint8_t days_in_this_month = MONTH_DAYS_TABLE[IS_LEAP_YEAR(year)][month - 1]; \
ERR_FAIL_COND_V_MSG(day > days_in_this_month, ret, "Invalid day value of: " + itos(day) + " which is larger than the maximum for this month, " + itos(days_in_this_month) + "."); ERR_FAIL_COND_V_MSG(day > days_in_this_month, ret, "Invalid day value of: " + itos(day) + " which is larger than the maximum for this month, " + itos(days_in_this_month) + ".");
@ -127,10 +132,10 @@ VARIANT_ENUM_CAST(Time::Weekday);
#define PARSE_ISO8601_STRING(ret) \ #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; \ int day = 1; \
uint8_t hour = 0; \ int hour = 0; \
uint8_t minute = 0; \ int minute = 0; \
uint8_t second = 0; \ int second = 0; \
{ \ { \
bool has_date = false, has_time = false; \ bool has_date = false, has_time = false; \
String date, time; \ String date, time; \
@ -178,11 +183,11 @@ VARIANT_ENUM_CAST(Time::Weekday);
/* Get all time values from the dictionary. If it doesn't exist, set the */ \ /* Get all time values from the dictionary. If it doesn't exist, set the */ \
/* values to the default values for Unix epoch (1970-01-01 00:00:00). */ \ /* values to the default values for Unix epoch (1970-01-01 00:00:00). */ \
int64_t year = p_datetime.has(YEAR_KEY) ? int64_t(p_datetime[YEAR_KEY]) : UNIX_EPOCH_YEAR_AD; \ int64_t year = p_datetime.has(YEAR_KEY) ? int64_t(p_datetime[YEAR_KEY]) : UNIX_EPOCH_YEAR_AD; \
Month month = Month((p_datetime.has(MONTH_KEY)) ? uint8_t(p_datetime[MONTH_KEY]) : 1); \ Month month = Month((p_datetime.has(MONTH_KEY)) ? int(p_datetime[MONTH_KEY]) : 1); \
uint8_t day = p_datetime.has(DAY_KEY) ? uint8_t(p_datetime[DAY_KEY]) : 1; \ int day = p_datetime.has(DAY_KEY) ? int(p_datetime[DAY_KEY]) : 1; \
uint8_t hour = p_datetime.has(HOUR_KEY) ? uint8_t(p_datetime[HOUR_KEY]) : 0; \ int hour = p_datetime.has(HOUR_KEY) ? int(p_datetime[HOUR_KEY]) : 0; \
uint8_t minute = p_datetime.has(MINUTE_KEY) ? uint8_t(p_datetime[MINUTE_KEY]) : 0; \ int minute = p_datetime.has(MINUTE_KEY) ? int(p_datetime[MINUTE_KEY]) : 0; \
uint8_t second = p_datetime.has(SECOND_KEY) ? uint8_t(p_datetime[SECOND_KEY]) : 0; int second = p_datetime.has(SECOND_KEY) ? int(p_datetime[SECOND_KEY]) : 0;
Time *Time::singleton = nullptr; Time *Time::singleton = nullptr;

View file

@ -51,7 +51,7 @@ class Time : public Object {
public: public:
static Time *get_singleton(); static Time *get_singleton();
enum Month : uint8_t { enum Month {
/// Start at 1 to follow Windows SYSTEMTIME structure /// Start at 1 to follow Windows SYSTEMTIME structure
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx /// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx
MONTH_JANUARY = 1, MONTH_JANUARY = 1,