'2009-02-29', # Invalid leap day
'2019-W53-1', # No week 53 in 2019
'2020-W54-1', # No week 54
+ '0000-W25-1', # Invalid year
+ '10000-W25-1', # Invalid year
+ '2020-W25-0', # Invalid day-of-week
+ '2020-W25-8', # Invalid day-of-week
'2009\ud80002\ud80028', # Separators are surrogate codepoints
]
static int
iso_to_ymd(const int iso_year, const int iso_week, const int iso_day,
int *year, int *month, int *day) {
+ // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5)
+ if (iso_year < MINYEAR || iso_year > MAXYEAR) {
+ return -4;
+ }
if (iso_week <= 0 || iso_week >= 53) {
int out_of_range = 1;
if (iso_week == 53) {
* -2: Inconsistent date separator usage
* -3: Failed to parse ISO week.
* -4: Failed to parse ISO day.
- * -5, -6: Failure in iso_to_ymd
+ * -5, -6, -7: Failure in iso_to_ymd
*/
const char *p = dtstr;
p = parse_digits(p, year, 4);
return NULL;
}
- // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5)
- if (year < MINYEAR || year > MAXYEAR) {
- PyErr_Format(PyExc_ValueError, "Year is out of range: %d", year);
- return NULL;
- }
-
int month;
int rv = iso_to_ymd(year, week, day, &year, &month, &day);
+ if (rv == -4) {
+ PyErr_Format(PyExc_ValueError, "Year is out of range: %d", year);
+ return NULL;
+ }
if (rv == -2) {
PyErr_Format(PyExc_ValueError, "Invalid week: %d", week);