Skip to content

Commit 4494a40

Browse files
committed
Fixed filesystem.get_content_mimetype() crashing on non-guessable byte stream
1 parent e29e6be commit 4494a40

File tree

5 files changed

+150
-3
lines changed

5 files changed

+150
-3
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project are documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) (as of version 1.5.0).
77

8+
## [1.6.2] - 2022-07-29
9+
10+
### Changed
11+
12+
- Fixed `filesystem.get_content_mimetype()` crashing on non-guessable byte stream
13+
814
## [1.6.1] - 2022-07-26
915

1016
### Changed

src/zimscraperlib/VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.6.1
1+
1.6.2

src/zimscraperlib/filesystem.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ def get_file_mimetype(fpath: pathlib.Path) -> str:
3131
def get_content_mimetype(content: bytes) -> str:
3232
"""MIME Type of content retrieved from magic headers"""
3333

34-
detected_mime = magic.detect_from_content(content).mime_type
34+
try:
35+
detected_mime = magic.detect_from_content(content).mime_type
36+
except UnicodeDecodeError:
37+
return "application/octet-stream"
3538
return MIME_OVERRIDES.get(detected_mime, detected_mime)
3639

3740

tests/conftest.py

+136
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,139 @@ def real_zim_file(tmpdir_factory):
165165
dst,
166166
)
167167
return dst
168+
169+
170+
@pytest.fixture(scope="session")
171+
def undecodable_byte_stream():
172+
173+
return (
174+
b"\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00"
175+
b"\x00\x00\x01\x00\xfb\xff~\x00\x08\x00\xfd\xff\x01\x00\x00\x00"
176+
b"\xff\xff\x03\x00\xf6\xffz\x00\x12\x00\xfa\xff\x02\x00\x00\x00"
177+
b"\xff\xff\x04\x00\xf3\xffv\x00\x1b\x00\xf7\xff\x03\x00\xff\xff"
178+
b"\xff\xff\x04\x00\xf0\xffp\x00%\x00\xf5\xff\x04\x00\xff\xff"
179+
b"\xff\xff\x05\x00\xee\xffi\x000\x00\xf2\xff\x04\x00\xff\xff"
180+
b"\xff\xff\x05\x00\xed\xffa\x00:\x00\xf0\xff\x05\x00\xff\xff"
181+
b"\xff\xff\x06\x00\xed\xffX\x00D\x00\xee\xff\x05\x00\xff\xff"
182+
b"\xff\xff\x06\x00\xed\xffN\x00N\x00\xed\xff\x06\x00\xff\xff"
183+
b"\xff\xff\x05\x00\xee\xffD\x00X\x00\xed\xff\x06\x00\xff\xff"
184+
b"\xff\xff\x05\x00\xf0\xff:\x00a\x00\xed\xff\x05\x00\xff\xff"
185+
b"\xff\xff\x04\x00\xf2\xff0\x00i\x00\xee\xff\x05\x00\xff\xff"
186+
b"\xff\xff\x04\x00\xf5\xff%\x00p\x00\xf0\xff\x04\x00\xff\xff"
187+
b"\xff\xff\x03\x00\xf7\xff\x1b\x00v\x00\xf3\xff\x04\x00\xff\xff"
188+
b"\x00\x00\x02\x00\xfa\xff\x12\x00z\x00\xf6\xff\x03\x00\xff\xff"
189+
b"\x00\x00\x01\x00\xfd\xff\x08\x00~\x00\xfb\xff\x01\x00\x00\x00"
190+
b"\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00"
191+
b"\xfd\xff\xff\xff \x00@\x00&\x00\x01\x00\xfd\xff\x00\x00"
192+
b"\xfe\xff\xfe\xff\x1d\x00?\x00)\x00\x02\x00\xfd\xff\x00\x00"
193+
b"\xfe\xff\xfe\xff\x1a\x00?\x00+\x00\x04\x00\xfc\xff\x00\x00"
194+
b"\xfe\xff\xfd\xff\x18\x00>\x00.\x00\x05\x00\xfc\xff\x00\x00"
195+
b"\xfe\xff\xfd\xff\x15\x00<\x001\x00\x07\x00\xfc\xff\x00\x00"
196+
b"\xff\xff\xfc\xff\x12\x00;\x003\x00\t\x00\xfc\xff\x00\x00"
197+
b"\xff\xff\xfc\xff\x10\x009\x005\x00\x0c\x00\xfc\xff\xff\xff"
198+
b"\xff\xff\xfc\xff\x0e\x007\x007\x00\x0e\x00\xfc\xff\xff\xff"
199+
b"\xff\xff\xfc\xff\x0c\x005\x009\x00\x10\x00\xfc\xff\xff\xff"
200+
b"\x00\x00\xfc\xff\t\x003\x00;\x00\x12\x00\xfc\xff\xff\xff"
201+
b"\x00\x00\xfc\xff\x07\x001\x00<\x00\x15\x00\xfd\xff\xfe\xff"
202+
b"\x00\x00\xfc\xff\x05\x00.\x00>\x00\x18\x00\xfd\xff\xfe\xff"
203+
b"\x00\x00\xfc\xff\x04\x00+\x00?\x00\x1a\x00\xfe\xff\xfe\xff"
204+
b"\x00\x00\xfd\xff\x02\x00)\x00?\x00\x1d\x00\xfe\xff\xfe\xff"
205+
b"\x00\x00\xfd\xff\x01\x00&\x00@\x00 \x00\xff\xff\xfd\xff"
206+
b"\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00"
207+
b"\xff\xff\x03\x00\xf9\xff\x7f\x00\x08\x00\xfd\xff\x01\x00\x00\x00"
208+
b"\xfe\xff\x05\x00\xf3\xff}\x00\x11\x00\xfa\xff\x03\x00\xff\xff"
209+
b"\xfd\xff\x07\x00\xef\xffy\x00\x1b\x00\xf6\xff\x05\x00\xfe\xff"
210+
b"\xfc\xff\t\x00\xec\xffs\x00%\x00\xf3\xff\x06\x00\xfe\xff"
211+
b"\xfc\xff\n\x00\xe9\xffl\x000\x00\xf0\xff\x08\x00\xfd\xff"
212+
b"\xfc\xff\n\x00\xe8\xffd\x00;\x00\xed\xff\t\x00\xfd\xff"
213+
b"\xfc\xff\x0b\x00\xe8\xffZ\x00F\x00\xeb\xff\n\x00\xfc\xff"
214+
b"\xfc\xff\x0b\x00\xe9\xffP\x00P\x00\xe9\xff\x0b\x00\xfc\xff"
215+
b"\xfc\xff\n\x00\xeb\xffF\x00Z\x00\xe8\xff\x0b\x00\xfc\xff"
216+
b"\xfd\xff\t\x00\xed\xff;\x00d\x00\xe8\xff\n\x00\xfc\xff"
217+
b"\xfd\xff\x08\x00\xf0\xff0\x00l\x00\xe9\xff\n\x00\xfc\xff"
218+
b"\xfe\xff\x06\x00\xf3\xff%\x00s\x00\xec\xff\t\x00\xfc\xff"
219+
b"\xfe\xff\x05\x00\xf6\xff\x1b\x00y\x00\xef\xff\x07\x00\xfd\xff"
220+
b"\xff\xff\x03\x00\xfa\xff\x11\x00}\x00\xf3\xff\x05\x00\xfe\xff"
221+
b"\x00\x00\x01\x00\xfd\xff\x08\x00\x7f\x00\xf9\xff\x03\x00\xff\xff"
222+
b"\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00"
223+
b"\x00\x00\x00\x00\x00\x00x\x00\x08\x00\x00\x00\x00\x00\x00\x00"
224+
b"\x00\x00\x00\x00\x00\x00p\x00\x10\x00\x00\x00\x00\x00\x00\x00"
225+
b"\x00\x00\x00\x00\x00\x00h\x00\x18\x00\x00\x00\x00\x00\x00\x00"
226+
b"\x00\x00\x00\x00\x00\x00`\x00 \x00\x00\x00\x00\x00\x00\x00"
227+
b"\x00\x00\x00\x00\x00\x00X\x00(\x00\x00\x00\x00\x00\x00\x00"
228+
b"\x00\x00\x00\x00\x00\x00P\x000\x00\x00\x00\x00\x00\x00\x00"
229+
b"\x00\x00\x00\x00\x00\x00H\x008\x00\x00\x00\x00\x00\x00\x00"
230+
b"\x00\x00\x00\x00\x00\x00@\x00@\x00\x00\x00\x00\x00\x00\x00"
231+
b"\x00\x00\x00\x00\x00\x008\x00H\x00\x00\x00\x00\x00\x00\x00"
232+
b"\x00\x00\x00\x00\x00\x000\x00P\x00\x00\x00\x00\x00\x00\x00"
233+
b"\x00\x00\x00\x00\x00\x00(\x00X\x00\x00\x00\x00\x00\x00\x00"
234+
b"\x00\x00\x00\x00\x00\x00 \x00`\x00\x00\x00\x00\x00\x00\x00"
235+
b"\x00\x00\x00\x00\x00\x00\x18\x00h\x00\x00\x00\x00\x00\x00\x00"
236+
b"\x00\x00\x00\x00\x00\x00\x10\x00p\x00\x00\x00\x00\x00\x00\x00"
237+
b"\x00\x00\x00\x00\x00\x00\x08\x00x\x00\x00\x00\x00\x00\x00\x00"
238+
b"\x02\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00"
239+
b"\x03\x00\x00\x00\x06\x00\x00\x00\x08\x01\x00\x00\x07\x00\x00\x00"
240+
b"\x03\x01\x00\x00\x08\x00\x00\x00\x07\x01\x00\x00\t\x00\x00\x00"
241+
b"\t\x01\x00\x00\n\x00\x00\x00\n\x01\x00\x00\x0b\x00\x00\x00"
242+
b"\x0b\x01\x00\x00\x0c\x00\x00\x00\x00\x01\x00\x00\r\x00\x00\x00"
243+
b"\x01\x01\x00\x00\x0e\x00\x00\x00\x80\x00\x00\x00\x0f\x00\x00\x00"
244+
b"\x05\x01\x00\x00\x10\x00\x00\x00\x06\x01\x00\x00\x11\x00\x00\x00"
245+
b"\x04\x01\x00\x00\x12\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00"
246+
b"\x07\x14!.;HUbo|\x89\x96\xa3\xb0\xbd\xca"
247+
b"\xd7\xe4\xf1\xfe\x01\x02\x03\x04\x05\x06\x08\t\n\x0b\x0c\r"
248+
b"\x0e\x0f\x10\x11\x12\x13\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e"
249+
b"\x1f \"#$%&'()*+,-/0"
250+
b"123456789:<=>?@A"
251+
b"BCDEFGIJKLMNOPQR"
252+
b"STVWXYZ[\\]^_`acd"
253+
b"efghijklmnpqrstu"
254+
b"vwxyz{}~\x7f\x80\x81\x82\x83\x84\x85\x86"
255+
b"\x87\x88\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x97\x98"
256+
b"\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa4\xa5\xa6\xa7\xa8\xa9"
257+
b"\xaa\xab\xac\xad\xae\xaf\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba"
258+
b"\xbb\xbc\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xcb\xcc"
259+
b"\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xd9\xda\xdb\xdc\xdd"
260+
b"\xde\xdf\xe0\xe1\xe2\xe3\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee"
261+
b"\xef\xf0\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfd\x00"
262+
b"\x00\x07\x06\x06\x05\x05\x05\x05\x04\x04\x04\x04\x04\x04\x04\x04"
263+
b"\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03"
264+
b"\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02"
265+
b"\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02"
266+
b"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
267+
b"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
268+
b"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
269+
b"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
270+
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
271+
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
272+
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
273+
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
274+
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
275+
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
276+
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
277+
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
278+
b"\x9f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
279+
b"\xa5\x91\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
280+
b"\xad\x94\x8c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
281+
b"\xb0\x9b\x8c\x87\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
282+
b"\xb4\x9d\x8d\x86\x82\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
283+
b"\xfe\xfe\xfe\xfc\xf9\xf3\xe6\xc4\xb1\x99\x8c\x85\x82\x81\x00\x00"
284+
b"\x00\x01\x01\x02\x02\x02\x03\x03\x03\x03\x04\x04\x04\x04\x04\x04"
285+
b"\x04\x04\x04\x04\x04\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
286+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
287+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
288+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
289+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
290+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
291+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
292+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
293+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
294+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
295+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
296+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
297+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
298+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
299+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
300+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
301+
b"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
302+
b""
303+
)

tests/filesystem/test_filesystem.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ def test_file_mimetype(png_image, jpg_image):
1414
assert get_file_mimetype(jpg_image) == "image/jpeg"
1515

1616

17-
def test_content_mimetype(png_image, jpg_image):
17+
def test_content_mimetype(png_image, jpg_image, undecodable_byte_stream):
1818
with open(png_image, "rb") as fh:
1919
assert get_content_mimetype(fh.read(64)) == "image/png"
2020

2121
with open(jpg_image, "rb") as fh:
2222
assert get_content_mimetype(fh.read(64)) == "image/jpeg"
2323

24+
assert get_content_mimetype(undecodable_byte_stream) == "application/octet-stream"
25+
2426

2527
def test_mime_overrides(svg_image):
2628
mime_map = [(svg_image, "image/svg+xml")]

0 commit comments

Comments
 (0)