Skip to content

Commit 3b0047d

Browse files
Alexey Izbyshevtaleinat
authored andcommitted
bpo-34482: test datetime classes' handling of non-UTF-8-encodable strings (GH-8878)
1 parent 83a0765 commit 3b0047d

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

Lib/test/datetimetester.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,8 @@ def test_tzname(self):
303303
self.assertEqual('UTC+09:30', timezone(9.5 * HOUR).tzname(None))
304304
self.assertEqual('UTC-00:01', timezone(timedelta(minutes=-1)).tzname(None))
305305
self.assertEqual('XYZ', timezone(-5 * HOUR, 'XYZ').tzname(None))
306+
# bpo-34482: Check that surrogates are handled properly.
307+
self.assertEqual('\ud800', timezone(ZERO, '\ud800').tzname(None))
306308

307309
# Sub-minute offsets:
308310
self.assertEqual('UTC+01:06:40', timezone(timedelta(0, 4000)).tzname(None))
@@ -1308,6 +1310,12 @@ def test_strftime(self):
13081310
except ValueError:
13091311
pass
13101312

1313+
# bpo-34482: Check that surrogates don't cause a crash.
1314+
try:
1315+
t.strftime('%y\ud800%m')
1316+
except UnicodeEncodeError:
1317+
pass
1318+
13111319
#check that this standard extension works
13121320
t.strftime("%f")
13131321

@@ -1747,6 +1755,9 @@ def test_isoformat(self):
17471755
self.assertEqual(t.isoformat('T'), "0001-02-03T04:05:01.000123")
17481756
self.assertEqual(t.isoformat(' '), "0001-02-03 04:05:01.000123")
17491757
self.assertEqual(t.isoformat('\x00'), "0001-02-03\x0004:05:01.000123")
1758+
# bpo-34482: Check that surrogates are handled properly.
1759+
self.assertEqual(t.isoformat('\ud800'),
1760+
"0001-02-03\ud80004:05:01.000123")
17501761
self.assertEqual(t.isoformat(timespec='hours'), "0001-02-03T04")
17511762
self.assertEqual(t.isoformat(timespec='minutes'), "0001-02-03T04:05")
17521763
self.assertEqual(t.isoformat(timespec='seconds'), "0001-02-03T04:05:01")
@@ -1755,6 +1766,8 @@ def test_isoformat(self):
17551766
self.assertEqual(t.isoformat(timespec='auto'), "0001-02-03T04:05:01.000123")
17561767
self.assertEqual(t.isoformat(sep=' ', timespec='minutes'), "0001-02-03 04:05")
17571768
self.assertRaises(ValueError, t.isoformat, timespec='foo')
1769+
# bpo-34482: Check that surrogates are handled properly.
1770+
self.assertRaises(ValueError, t.isoformat, timespec='\ud800')
17581771
# str is ISO format with the separator forced to a blank.
17591772
self.assertEqual(str(t), "0001-02-03 04:05:01.000123")
17601773

@@ -2286,6 +2299,19 @@ def test_strptime(self):
22862299
self.assertIs(type(expected), self.theclass)
22872300
self.assertIs(type(got), self.theclass)
22882301

2302+
# bpo-34482: Check that surrogates are handled properly.
2303+
inputs = [
2304+
('2004-12-01\ud80013:02:47.197', '%Y-%m-%d\ud800%H:%M:%S.%f'),
2305+
('2004\ud80012-01 13:02:47.197', '%Y\ud800%m-%d %H:%M:%S.%f'),
2306+
('2004-12-01 13:02\ud80047.197', '%Y-%m-%d %H:%M\ud800%S.%f'),
2307+
]
2308+
for string, format in inputs:
2309+
with self.subTest(string=string, format=format):
2310+
expected = _strptime._strptime_datetime(self.theclass, string,
2311+
format)
2312+
got = self.theclass.strptime(string, format)
2313+
self.assertEqual(expected, got)
2314+
22892315
strptime = self.theclass.strptime
22902316
self.assertEqual(strptime("+0002", "%z").utcoffset(), 2 * MINUTE)
22912317
self.assertEqual(strptime("-0002", "%z").utcoffset(), -2 * MINUTE)
@@ -2353,6 +2379,12 @@ def test_more_strftime(self):
23532379
t = t.replace(tzinfo=tz)
23542380
self.assertEqual(t.strftime("%z"), "-0200" + z)
23552381

2382+
# bpo-34482: Check that surrogates don't cause a crash.
2383+
try:
2384+
t.strftime('%y\ud800%m %H\ud800%M')
2385+
except UnicodeEncodeError:
2386+
pass
2387+
23562388
def test_extract(self):
23572389
dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234)
23582390
self.assertEqual(dt.date(), date(2002, 3, 4))
@@ -2878,6 +2910,8 @@ def test_isoformat(self):
28782910
self.assertEqual(t.isoformat(timespec='microseconds'), "12:34:56.123456")
28792911
self.assertEqual(t.isoformat(timespec='auto'), "12:34:56.123456")
28802912
self.assertRaises(ValueError, t.isoformat, timespec='monkey')
2913+
# bpo-34482: Check that surrogates are handled properly.
2914+
self.assertRaises(ValueError, t.isoformat, timespec='\ud800')
28812915

28822916
t = self.theclass(hour=12, minute=34, second=56, microsecond=999500)
28832917
self.assertEqual(t.isoformat(timespec='milliseconds'), "12:34:56.999")
@@ -2928,6 +2962,12 @@ def test_strftime(self):
29282962
# A naive object replaces %z and %Z with empty strings.
29292963
self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''")
29302964

2965+
# bpo-34482: Check that surrogates don't cause a crash.
2966+
try:
2967+
t.strftime('%H\ud800%M')
2968+
except UnicodeEncodeError:
2969+
pass
2970+
29312971
def test_format(self):
29322972
t = self.theclass(1, 2, 3, 4)
29332973
self.assertEqual(t.__format__(''), str(t))

0 commit comments

Comments
 (0)