From 0334e68f956a18350fc2cba872aef54e57c51e14 Mon Sep 17 00:00:00 2001 From: Yay295 Date: Thu, 12 Jan 2023 08:36:17 -0600 Subject: [PATCH] add more eps file tests --- Tests/test_file_eps.py | 109 ++++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 45 deletions(-) diff --git a/Tests/test_file_eps.py b/Tests/test_file_eps.py index 9558d149f..bded99cf1 100644 --- a/Tests/test_file_eps.py +++ b/Tests/test_file_eps.py @@ -28,34 +28,47 @@ FILE2_COMPARE_SCALE2 = "Tests/images/non_zero_bb_scale2.png" # EPS test files with binary preview FILE3 = "Tests/images/binary_preview_map.eps" +# Three unsigned 32bit little-endian values: +# 0xC6D3D0C5 magic number +# byte position of start of postscript section (12) +# byte length of postscript section (0) +# this byte length isn't valid, but we don't read it +simple_binary_header = b"\xc5\xd0\xd3\xc6\x0c\x00\x00\x00\x00\x00\x00\x00" + +# taken from page 8 of the specification +# https://web.archive.org/web/20220120164601/https://www.adobe.com/content/dam/acom/en/devnet/actionscript/articles/5002.EPSF_Spec.pdf +simple_eps_file = ( + b"%!PS-Adobe-3.0 EPSF-3.0", + b"%%BoundingBox: 5 5 105 105", + b"10 setlinewidth", + b"10 10 moveto", + b"0 90 rlineto 90 0 rlineto 0 -90 rlineto closepath", + b"stroke", +) +simple_eps_file_with_comments = ( + simple_eps_file[:1] + + ( + b"%%Comment1: Some Value", + b"%%SecondComment: Another Value", + ) + + simple_eps_file[1:] +) +simple_eps_file_without_version = simple_eps_file[1:] +simple_eps_file_without_boundingbox = simple_eps_file[:1] + simple_eps_file[2:] + @pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available") -def test_sanity(): - # Regular scale - with Image.open(FILE1) as image1: - image1.load() - assert image1.mode == "RGB" - assert image1.size == (460, 352) - assert image1.format == "EPS" - - with Image.open(FILE2) as image2: - image2.load() - assert image2.mode == "RGB" - assert image2.size == (360, 252) - assert image2.format == "EPS" - - # Double scale - with Image.open(FILE1) as image1_scale2: - image1_scale2.load(scale=2) - assert image1_scale2.mode == "RGB" - assert image1_scale2.size == (920, 704) - assert image1_scale2.format == "EPS" - - with Image.open(FILE2) as image2_scale2: - image2_scale2.load(scale=2) - assert image2_scale2.mode == "RGB" - assert image2_scale2.size == (720, 504) - assert image2_scale2.format == "EPS" +@pytest.mark.parametrize( + ("filename", "size"), ((FILE1, (460, 352)), (FILE2, (360, 252))) +) +@pytest.mark.parametrize("scale", (1, 2)) +def test_sanity(filename, size, scale): + expected_size = tuple(s * scale for s in size) + with Image.open(filename) as image: + image.load(scale=scale) + assert image.mode == "RGB" + assert image.size == expected_size + assert image.format == "EPS" @pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available") @@ -69,18 +82,36 @@ def test_load(): def test_invalid_file(): invalid_file = "Tests/images/flower.jpg" - with pytest.raises(SyntaxError): EpsImagePlugin.EpsImageFile(invalid_file) +def test_binary_header_only(): + data = io.BytesIO(simple_binary_header) + with pytest.raises(SyntaxError, match='EPS header missing "%!PS-Adobe" comment'): + EpsImagePlugin.EpsImageFile(data) + + +@pytest.mark.parametrize("prefix", (b"", simple_binary_header)) +def test_missing_version_comment(prefix): + data = io.BytesIO(prefix + b"\n".join(simple_eps_file_without_version)) + with pytest.raises(SyntaxError): + EpsImagePlugin.EpsImageFile(data) + + +@pytest.mark.parametrize("prefix", (b"", simple_binary_header)) +def test_missing_boundingbox_comment(prefix): + data = io.BytesIO(prefix + b"\n".join(simple_eps_file_without_boundingbox)) + with pytest.raises(SyntaxError, match='EPS header missing "%%BoundingBox" comment'): + EpsImagePlugin.EpsImageFile(data) + + @mark_if_feature_version( pytest.mark.valgrind_known_error, "libjpeg_turbo", "2.0", reason="Known Failing" ) @pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available") def test_cmyk(): with Image.open("Tests/images/pil_sample_cmyk.eps") as cmyk_image: - assert cmyk_image.mode == "CMYK" assert cmyk_image.size == (100, 100) assert cmyk_image.format == "EPS" @@ -101,7 +132,7 @@ def test_showpage(): with Image.open("Tests/images/reqd_showpage.png") as target: # should not crash/hang plot_image.load() - # fonts could be slightly different + # fonts could be slightly different assert_image_similar(plot_image, target, 6) @@ -112,7 +143,7 @@ def test_transparency(): assert plot_image.mode == "RGBA" with Image.open("Tests/images/reqd_showpage_transparency.png") as target: - # fonts could be slightly different + # fonts could be slightly different assert_image_similar(plot_image, target, 6) @@ -207,7 +238,6 @@ def test_resize(filename): @pytest.mark.parametrize("filename", (FILE1, FILE2)) def test_thumbnail(filename): # Issue #619 - # Arrange with Image.open(filename) as im: new_size = (100, 100) im.thumbnail(new_size) @@ -256,24 +286,13 @@ def test_readline_psfile(tmp_path): _test_readline_file_psfile(s, ending) +@pytest.mark.parametrize("prefix", (b"", simple_binary_header)) @pytest.mark.parametrize( "line_ending", (b"\r\n", b"\n", b"\n\r", b"\r"), ) -def test_readline(line_ending): - simple_file = line_ending.join( - ( - b"%!PS-Adobe-3.0 EPSF-3.0", - b"%%Comment1: Some Value", - b"%%SecondComment: Another Value", - b"%%BoundingBox: 5 5 105 105", - b"10 setlinewidth", - b"10 10 moveto", - b"0 90 rlineto 90 0 rlineto 0 -90 rlineto closepath", - b"stroke", - ) - ) - +def test_readline(prefix, line_ending): + simple_file = prefix + line_ending.join(simple_eps_file_with_comments) data = io.BytesIO(simple_file) test_file = EpsImagePlugin.EpsImageFile(data) assert test_file.info["Comment1"] == "Some Value"