-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
Copy pathtest_xobject_image_helpers.py
128 lines (114 loc) · 4.03 KB
/
test_xobject_image_helpers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"""Test the pypdf._xobj_image_helpers module."""
from io import BytesIO
import pytest
from pypdf import PdfReader
from pypdf._xobj_image_helpers import _extended_image_frombytes, _handle_flate
from pypdf.errors import EmptyImageDataError, PdfReadError
from pypdf.generic import ArrayObject, DecodedStreamObject, NameObject, NumberObject
from . import get_data_from_url
@pytest.mark.enable_socket
def test_get_imagemode_recursion_depth():
"""Avoid infinite recursion for nested color spaces."""
url = "https://github.com/py-pdf/pypdf/files/12814018/out1.pdf"
name = "issue2240.pdf"
# Simple example: Just let the color space object reference itself.
# The alternative would be to generate a chain of referencing objects.
content = get_data_from_url(url, name=name)
source = b"\n10 0 obj\n[ /DeviceN [ /HKS#2044#20K /Magenta /Yellow /Black ] 7 0 R 11 0 R 12 0 R ]\nendobj\n"
target = b"\n10 0 obj\n[ /DeviceN [ /HKS#2044#20K /Magenta /Yellow /Black ] 10 0 R 11 0 R 12 0 R ]\nendobj\n"
reader = PdfReader(BytesIO(content.replace(source, target)))
with pytest.raises(
PdfReadError,
match="Color spaces nested too deeply. If required, consider increasing MAX_IMAGE_MODE_NESTING_DEPTH.",
):
reader.pages[0].images[0]
def test_handle_flate__image_mode_1(caplog):
data = b"\x00\xe0\x00"
lookup = DecodedStreamObject()
expected_data = [
(66, 66, 66),
(66, 66, 66),
(66, 66, 66),
(0, 19, 55),
(0, 19, 55),
(0, 19, 55),
(66, 66, 66),
(66, 66, 66),
(66, 66, 66),
]
# No trailing data.
lookup.set_data(b"\x42\x42\x42\x00\x13\x37")
result = _handle_flate(
size=(3, 3),
data=data,
mode="1",
color_space=ArrayObject(
[NameObject("/Indexed"), NameObject("/DeviceRGB"), NumberObject(1), lookup]
),
colors=2,
obj_as_text="dummy",
)
assert expected_data == list(result[0].getdata())
assert not caplog.text
# Trailing whitespace.
lookup.set_data(b"\x42\x42\x42\x00\x13\x37 \x0a")
result = _handle_flate(
size=(3, 3),
data=data,
mode="1",
color_space=ArrayObject(
[NameObject("/Indexed"), NameObject("/DeviceRGB"), NumberObject(1), lookup]
),
colors=2,
obj_as_text="dummy",
)
assert expected_data == list(result[0].getdata())
assert not caplog.text
# Trailing non-whitespace character.
lookup.set_data(b"\x42\x42\x42\x00\x13\x37\x12")
result = _handle_flate(
size=(3, 3),
data=data,
mode="1",
color_space=ArrayObject(
[
NameObject("/Indexed"),
NameObject("/DeviceRGB"),
NumberObject(1),
lookup,
]
),
colors=2,
obj_as_text="dummy",
)
assert expected_data == list(result[0].getdata())
assert "Too many lookup values: Expected 6, got 7." in caplog.text
# Not enough lookup data.
# `\xe0` of the original input (the middle part) does not use `0x37 = 55` for the lookup
# here, but received a custom padding of `0`.
lookup.set_data(b"\x42\x42\x42\x00\x13")
caplog.clear()
expected_short_data = [entry if entry[0] == 66 else (0, 19, 0) for entry in expected_data]
result = _handle_flate(
size=(3, 3),
data=data,
mode="1",
color_space=ArrayObject(
[
NameObject("/Indexed"),
NameObject("/DeviceRGB"),
NumberObject(1),
lookup,
]
),
colors=2,
obj_as_text="dummy",
)
assert expected_short_data == list(result[0].getdata())
assert "Not enough lookup values: Expected 6, got 5." in caplog.text
def test_extended_image_frombytes_zero_data():
mode = "RGB"
size = (1, 1)
data = b""
with pytest.raises(EmptyImageDataError, match="Data is 0 bytes, cannot process an image from empty data."):
_extended_image_frombytes(mode, size, data)