Skip to content

Commit eb8e176

Browse files
committed
Retain non-sanitized dtstr for error printing
This does not create an extra string, it just holds on to a reference to the original input string for purposes of creating the error message.
1 parent 6d6f3d0 commit eb8e176

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

Lib/test/datetimetester.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import os
1414
import pickle
1515
import random
16+
import re
1617
import struct
1718
import unittest
1819

@@ -2676,6 +2677,14 @@ def test_fromisoformat_fails_datetime(self):
26762677
with self.assertRaises(ValueError):
26772678
self.theclass.fromisoformat(bad_str)
26782679

2680+
def test_fromisoformat_fails_surrogate(self):
2681+
# Test that when fromisoformat() fails with a surrogate character as
2682+
# the separator, the error message contains the original string
2683+
dtstr = "2018-01-03\ud80001:0113"
2684+
2685+
with self.assertRaisesRegex(ValueError, re.escape(repr(dtstr))):
2686+
self.theclass.fromisoformat(dtstr)
2687+
26792688
def test_fromisoformat_utc(self):
26802689
dt_str = '2014-04-19T13:21:13+00:00'
26812690
dt = self.theclass.fromisoformat(dt_str)

Modules/_datetimemodule.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4902,13 +4902,13 @@ datetime_fromisoformat(PyObject* cls, PyObject *dtstr) {
49024902
}
49034903

49044904
int needs_decref = 0;
4905-
dtstr = _sanitize_isoformat_str(dtstr, &needs_decref);
4906-
if (dtstr == NULL) {
4905+
PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr, &needs_decref);
4906+
if (dtstr_clean == NULL) {
49074907
goto error;
49084908
}
49094909

49104910
Py_ssize_t len;
4911-
const char * dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
4911+
const char * dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
49124912

49134913
if (dt_ptr == NULL) {
49144914
goto invalid_string_error;
@@ -4960,7 +4960,7 @@ datetime_fromisoformat(PyObject* cls, PyObject *dtstr) {
49604960

49614961
Py_DECREF(tzinfo);
49624962
if (needs_decref) {
4963-
Py_DECREF(dtstr);
4963+
Py_DECREF(dtstr_clean);
49644964
}
49654965
return dt;
49664966

@@ -4969,7 +4969,7 @@ datetime_fromisoformat(PyObject* cls, PyObject *dtstr) {
49694969

49704970
error:
49714971
if (needs_decref) {
4972-
Py_DECREF(dtstr);
4972+
Py_DECREF(dtstr_clean);
49734973
}
49744974

49754975
return NULL;

0 commit comments

Comments
 (0)