From c40ea4f22a5cd3adebcb579a5366ac73263cbca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Reu=C3=9Fe?= Date: Sat, 18 Nov 2017 20:32:07 +0100 Subject: [PATCH] mediafile._safe_cast: be safer when converting to int MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The regex «[\+-]?[0-9]*» possibly matches a single minus/plus, which would then be passed on to int(), raising a ValueError from within _safe_cast. The test suite covered this for float, but not for int. We now make sure we actually have a number after the sign by using a Kleene plus. --- beets/mediafile.py | 7 ++----- docs/changelog.rst | 2 ++ test/test_mediafile_edge.py | 3 +++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/beets/mediafile.py b/beets/mediafile.py index b4c62612f..34ad49af7 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -159,11 +159,8 @@ def _safe_cast(out_type, val): elif not isinstance(val, six.string_types): val = six.text_type(val) # Get a number from the front of the string. - val = re.match(r'[\+-]?[0-9]*', val.strip()).group(0) - if not val: - return 0 - else: - return int(val) + match = re.match(r'[\+-]?[0-9]+', val.strip()) + return int(match.group(0)) if match else 0 elif out_type == bool: try: diff --git a/docs/changelog.rst b/docs/changelog.rst index 0cbfa27bd..0918a4967 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -71,6 +71,8 @@ Fixes: versions of Mutagen. :bug:`2716` * :doc:`/plugins/fetchart`: Fix: don't skip running the fetchart plugin during import, when the "Edit Candidates" option is used. :bug:`2734` +* Fix a crash when numeric metadata fields contain just a minus or plus sign + with no following numbers. For developers: diff --git a/test/test_mediafile_edge.py b/test/test_mediafile_edge.py index 657ca455d..8bf9e1916 100644 --- a/test/test_mediafile_edge.py +++ b/test/test_mediafile_edge.py @@ -105,6 +105,9 @@ class InvalidValueToleranceTest(unittest.TestCase): def test_safe_cast_string_to_int(self): self.assertEqual(_sc(int, u'something'), 0) + def test_safe_cast_string_to_int_with_no_numbers(self): + self.assertEqual(_sc(int, u'-'), 0) + def test_safe_cast_int_string_to_int(self): self.assertEqual(_sc(int, u'20'), 20)