diff --git a/Tests/images/hopper_long_name.im b/Tests/images/hopper_long_name.im new file mode 100644 index 00000000000..ff45b7c7539 Binary files /dev/null and b/Tests/images/hopper_long_name.im differ diff --git a/Tests/test_file_im.py b/Tests/test_file_im.py index 38ee6c6fbd2..30a9fd52a07 100644 --- a/Tests/test_file_im.py +++ b/Tests/test_file_im.py @@ -1,3 +1,5 @@ +import filecmp + import pytest from PIL import Image, ImImagePlugin @@ -15,6 +17,13 @@ def test_sanity(): assert im.format == "IM" +def test_name_limit(tmp_path): + out = str(tmp_path / ("name_limit_test" * 7 + ".im")) + with Image.open(TEST_IM) as im: + im.save(out) + assert filecmp.cmp(out, "Tests/images/hopper_long_name.im") + + @pytest.mark.skipif(is_pypy(), reason="Requires CPython") def test_unclosed_file(): def open(): diff --git a/src/PIL/ImImagePlugin.py b/src/PIL/ImImagePlugin.py index 427d6e986f7..8b03f35da8c 100644 --- a/src/PIL/ImImagePlugin.py +++ b/src/PIL/ImImagePlugin.py @@ -348,9 +348,14 @@ def _save(im, fp, filename): fp.write(("Image type: %s image\r\n" % image_type).encode("ascii")) if filename: - # Each line must be under length 100, or: SyntaxError("not an IM file") + # Each line must be 100 characters or less, + # or: SyntaxError("not an IM file") + # 8 characters are used for "Name: " and "\r\n" # Keep just the filename, ditch the potentially overlong path - fp.write(("Name: %s\r\n" % os.path.basename(filename)).encode("ascii")) + name, ext = os.path.splitext(os.path.basename(filename)) + name = "".join([name[: 92 - len(ext)], ext]) + + fp.write(("Name: %s\r\n" % name).encode("ascii")) fp.write(("Image size (x*y): %d*%d\r\n" % im.size).encode("ascii")) fp.write(("File size (no of images): %d\r\n" % frames).encode("ascii")) if im.mode in ["P", "PA"]: