Skip to content

Commit f851d74

Browse files
author
marat
committed
Add check for invalid specifiers
1 parent 2373670 commit f851d74

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

Lib/_pydatetime.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ def _need_normalize_century():
214214
return _normalize_century
215215

216216
def _make_dash_replacement(ch, timetuple):
217+
if ch not in 'dmHIMSjUWVy':
218+
raise ValueError('invalid format string')
219+
217220
fmt = '%' + ch
218221
val = _time.strftime(fmt, timetuple)
219222
return val.lstrip('0') or '0'

Lib/test/datetimetester.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1591,15 +1591,30 @@ def test_strftime(self):
15911591
self.assertEqual(t.strftime('x'*1000), 'x'*1000) # SF bug #1556784
15921592

15931593
# See gh-137165
1594-
if platform.system() in ('Darwin', 'iOS', 'FreeBSD'):
1594+
if platform.system() in ("Darwin", "iOS", "FreeBSD"):
15951595
self.assertEqual(t.strftime("m:%-m d:%-d y:%-y"), "m:3 d:2 y:05")
15961596
else:
1597-
if platform.system() == 'Windows':
1597+
if platform.system() == "Windows":
15981598
self.assertEqual(t.strftime("m:%#m d:%#d y:%#y"), "m:3 d:2 y:5")
15991599
self.assertEqual(t.strftime("m:%-m d:%-d y:%-y"), "m:3 d:2 y:5")
16001600

16011601
self.assertEqual(t.strftime("%-j. %-U. %-W. %-V."), "61. 9. 9. 9.")
16021602

1603+
if platform.system() in ("Windows", "Android"):
1604+
# invalid %-format specifiers must raise ValueError
1605+
self.assertRaises(ValueError, t.strftime, "%-1")
1606+
self.assertRaises(ValueError, t.strftime, "%--")
1607+
self.assertRaises(ValueError, t.strftime, "%-p")
1608+
self.assertRaises(ValueError, t.strftime, "%-#")
1609+
elif platform.system() in ("Darwin", "iOS", "FreeBSD"):
1610+
self.assertEqual(t.strftime("%-1"), "1")
1611+
self.assertEqual(t.strftime("%--"), "-")
1612+
self.assertEqual(t.strftime("%-#"), "#")
1613+
else:
1614+
self.assertEqual(t.strftime("%-1"), "%-1")
1615+
self.assertEqual(t.strftime("%--"), "%--")
1616+
self.assertEqual(t.strftime("%-#"), "%-#")
1617+
16031618
self.assertRaises(TypeError, t.strftime) # needs an arg
16041619
self.assertRaises(TypeError, t.strftime, "one", "two") # too many args
16051620
self.assertRaises(TypeError, t.strftime, 42) # arg wrong type

Modules/_datetimemodule.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2056,6 +2056,10 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
20562056
/* non-0-pad Windows and Android support */
20572057
else if (ch == '-' && i < flen) {
20582058
Py_UCS4 next_ch = PyUnicode_READ_CHAR(format, i);
2059+
if (strchr("dmHIMSjUWVy", (int)next_ch) == NULL) {
2060+
PyErr_SetString(PyExc_ValueError, "invalid format string");
2061+
goto Error;
2062+
}
20592063
i++;
20602064

20612065
Py_XDECREF(dash_replacement);

0 commit comments

Comments
 (0)