From 546366e3230b4410d3df21bb040dea58a89969ef Mon Sep 17 00:00:00 2001 From: Justin Applegate Date: Tue, 17 Jun 2025 11:19:51 -0400 Subject: [PATCH 1/3] Pickle FLOAT opcode now tolerates whitespace in C impl --- Lib/test/pickletester.py | 4 ++++ Modules/_pickle.c | 17 +++++------------ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 9a3a26a8400844..2ff93ed3d8b8c7 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -2963,6 +2963,10 @@ def test_float(self): pickle = self.dumps(value, proto) got = self.loads(pickle) self.assert_is_copy(value, got) + + def test_float_whitespace(self): + self.assertEqual(self.loads(b'F 1.2 \n.'), 1.2) + self.assertEqual(self.loads(b'F \t9 \n.'), 9) @run_with_locales('LC_ALL', 'de_DE', 'fr_FR', '') def test_float_format(self): diff --git a/Modules/_pickle.c b/Modules/_pickle.c index cf3ceb43fb3f3f..fed05036dea0b2 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -5445,25 +5445,18 @@ load_counted_long(PickleState *st, UnpicklerObject *self, int size) static int load_float(PickleState *state, UnpicklerObject *self) { - PyObject *value; - char *endptr, *s; + PyObject *value, *s_obj; + char *s; Py_ssize_t len; - double d; if ((len = _Unpickler_Readline(state, self, &s)) < 0) return -1; if (len < 2) return bad_readline(state); - errno = 0; - d = PyOS_string_to_double(s, &endptr, PyExc_OverflowError); - if (d == -1.0 && PyErr_Occurred()) - return -1; - if ((endptr[0] != '\n') && (endptr[0] != '\0')) { - PyErr_SetString(PyExc_ValueError, "could not convert string to float"); - return -1; - } - value = PyFloat_FromDouble(d); + s_obj = PyUnicode_FromString(s); + value = PyFloat_FromString(s_obj); + if (value == NULL) return -1; From 23a645636e00922b5ecc90287d75b7444dd85228 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Tue, 17 Jun 2025 15:21:27 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2025-06-17-15-21-25.gh-issue-135580.kl7Eux.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2025-06-17-15-21-25.gh-issue-135580.kl7Eux.rst diff --git a/Misc/NEWS.d/next/Library/2025-06-17-15-21-25.gh-issue-135580.kl7Eux.rst b/Misc/NEWS.d/next/Library/2025-06-17-15-21-25.gh-issue-135580.kl7Eux.rst new file mode 100644 index 00000000000000..4be11929acdba4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-06-17-15-21-25.gh-issue-135580.kl7Eux.rst @@ -0,0 +1 @@ +The :mod:`pickle` ``FLOAT`` opcode now tolerates trailing and leading whitespace in both C and Python implementations. From 2f3c2a0fd9d685262c92bf3aec11e17e1f1a3c20 Mon Sep 17 00:00:00 2001 From: Justin Applegate Date: Tue, 17 Jun 2025 11:23:40 -0400 Subject: [PATCH 3/3] Linting fix --- Lib/test/pickletester.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 2ff93ed3d8b8c7..c5b3b27ba1acef 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -2963,7 +2963,7 @@ def test_float(self): pickle = self.dumps(value, proto) got = self.loads(pickle) self.assert_is_copy(value, got) - + def test_float_whitespace(self): self.assertEqual(self.loads(b'F 1.2 \n.'), 1.2) self.assertEqual(self.loads(b'F \t9 \n.'), 9)