0.4.27-39-ga3ed086.unbreak-various-things.patch 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. Subject: Unbreak various things
  2. Origin: upstream, commit 0.4.27-39-ga3ed086 <https://github.com/ahupp/python-magic/commit/0.4.27-39-ga3ed086>
  3. Author: Adam Hupp <adam@hupp.org>
  4. Date: Tue Feb 18 10:55:05 2025 -0800
  5. Forwarded: not-needed
  6. * A merge to reduce error spam during loading broke .so
  7. loading in at least some (maybe all?) cases, where find_library
  8. doesn't return an absolute path.
  9. * Prematurely pushed some in-progress test changes that were super broken, all fixed now.
  10. --- a/magic/loader.py
  11. +++ b/magic/loader.py
  12. @@ -7,6 +7,7 @@
  13. logger = logging.getLogger(__name__)
  14. +
  15. def _lib_candidates_linux():
  16. """Yield possible libmagic library names on Linux.
  17. @@ -51,7 +52,7 @@
  18. "darwin": _lib_candidates_macos,
  19. "linux": _lib_candidates_linux,
  20. "win32": _lib_candidates_windows,
  21. - "sunos5": _lib_candidates_linux,
  22. + "sunos5": _lib_candidates_linux,
  23. }.get(sys.platform)
  24. if func is None:
  25. raise ImportError("python-magic: Unsupported platform: " + sys.platform)
  26. @@ -61,17 +62,20 @@
  27. def load_lib():
  28. + exc = []
  29. for lib in _lib_candidates():
  30. # find_library returns None when lib not found
  31. if lib is None:
  32. continue
  33. - if not os.path.exists(lib):
  34. - continue
  35. try:
  36. return ctypes.CDLL(lib)
  37. - except OSError:
  38. - logger.warning("Failed to load: " + lib, exc_info=True)
  39. + except OSError as e:
  40. + exc.append(e)
  41. +
  42. + msg = "\n".join([str(e) for e in exc])
  43. # It is better to raise an ImportError since we are importing magic module
  44. - raise ImportError("python-magic: failed to find libmagic. Check your installation")
  45. + raise ImportError(
  46. + "python-magic: failed to find libmagic. Check your installation: \n" + msg
  47. + )
  48. --- a/test/python_magic_test.py
  49. +++ b/test/python_magic_test.py
  50. @@ -5,6 +5,7 @@
  51. import shutil
  52. import sys
  53. import tempfile
  54. +from typing import List, Union
  55. import unittest
  56. import pytest
  57. @@ -19,140 +20,162 @@
  58. import magic
  59. +
  60. @dataclass
  61. class TestFile:
  62. file_name: str
  63. - mime_results: list[str]
  64. - text_results: list[str]
  65. - no_check_elf_results: list[str] | None
  66. + mime_results: List[str]
  67. + text_results: List[str]
  68. + no_check_elf_results: Union[List[str], None]
  69. buf_equals_file: bool = True
  70. +
  71. # magic_descriptor is broken (?) in centos 7, so don't run those tests
  72. SKIP_FROM_DESCRIPTOR = bool(os.environ.get("SKIP_FROM_DESCRIPTOR"))
  73. -COMMON_PLAIN = [
  74. - {},
  75. - {"check_soft": True},
  76. - {"check_soft": False},
  77. - {"check_json": True},
  78. - {"check_json": False},
  79. -]
  80. -
  81. -NO_SOFT = {"check_soft": False}
  82. -
  83. -COMMON_MIME = [{"mime": True, **k} for k in COMMON_PLAIN]
  84. +COMMON_PLAIN = [{}]
  85. +NO_SOFT = [{"check_soft": False}]
  86. +COMMON_MIME = [{"mime": True}]
  87. CASES = {
  88. - "magic._pyc_": [
  89. - (COMMON_MIME, [
  90. - "application/octet-stream",
  91. - "text/x-bytecode.python",
  92. - "application/x-bytecode.python",
  93. - ]),
  94. + b"magic._pyc_": [
  95. + (
  96. + COMMON_MIME,
  97. + [
  98. + "application/octet-stream",
  99. + "text/x-bytecode.python",
  100. + "application/x-bytecode.python",
  101. + ],
  102. + ),
  103. (COMMON_PLAIN, ["python 2.4 byte-compiled"]),
  104. (NO_SOFT, ["data"]),
  105. ],
  106. - "test.pdf": [
  107. + b"test.pdf": [
  108. (COMMON_MIME, ["application/pdf"]),
  109. - (COMMON_PLAIN, [
  110. - "PDF document, version 1.2",
  111. - "PDF document, version 1.2, 2 pages",
  112. - "PDF document, version 1.2, 2 page(s)",
  113. - ]),
  114. + (
  115. + COMMON_PLAIN,
  116. + [
  117. + "PDF document, version 1.2",
  118. + "PDF document, version 1.2, 2 pages",
  119. + "PDF document, version 1.2, 2 page(s)",
  120. + ],
  121. + ),
  122. (NO_SOFT, ["ASCII text"]),
  123. ],
  124. - "test.gz": [
  125. + b"test.gz": [
  126. (COMMON_MIME, ["application/gzip", "application/x-gzip"]),
  127. - (COMMON_PLAIN, [
  128. - 'gzip compressed data, was "test", from Unix, last modified: Sun Jun 29 01:32:52 2008',
  129. - 'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix',
  130. - 'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix, original size 15',
  131. - 'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix, original size modulo 2^32 15',
  132. - 'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix, truncated',
  133. - ]),
  134. - ({"extension": True}, [
  135. - # some versions return '' for the extensions of a gz file,
  136. - # including w/ the command line. Who knows...
  137. - "gz/tgz/tpz/zabw/svgz/adz/kmy/xcfgz",
  138. - "gz/tgz/tpz/zabw/svgz",
  139. - "",
  140. - "???",
  141. - ]),
  142. + (
  143. + COMMON_PLAIN,
  144. + [
  145. + 'gzip compressed data, was "test", from Unix, last modified: Sun Jun 29 01:32:52 2008',
  146. + 'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix',
  147. + 'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix, original size 15',
  148. + 'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix, original size modulo 2^32 15',
  149. + 'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix, truncated',
  150. + ],
  151. + ),
  152. + (
  153. + [{"extension": True}],
  154. + [
  155. + # some versions return '' for the extensions of a gz file,
  156. + # including w/ the command line. Who knows...
  157. + "gz/tgz/tpz/zabw/svgz/adz/kmy/xcfgz",
  158. + "gz/tgz/tpz/zabw/svgz",
  159. + "",
  160. + "???",
  161. + ],
  162. + ),
  163. (NO_SOFT, ["data"]),
  164. ],
  165. - "test.snappy.parquet": [
  166. + b"test.snappy.parquet": [
  167. (COMMON_MIME, ["application/octet-stream"]),
  168. (COMMON_PLAIN, ["Apache Parquet", "Par archive data"]),
  169. (NO_SOFT, ["data"]),
  170. ],
  171. - "test.json": [
  172. - # TODO: soft, no_json
  173. + b"test.json": [
  174. (COMMON_MIME, ["application/json"]),
  175. (COMMON_PLAIN, ["JSON text data"]),
  176. - ({"mime": True, "check_json": False}, [
  177. - "data",
  178. - ]),
  179. - (NO_SOFT, ["JSON text data"])
  180. + (
  181. + [{"mime": True, "check_json": False}],
  182. + [
  183. + "text/plain",
  184. + ],
  185. + ),
  186. + (NO_SOFT, ["JSON text data"]),
  187. ],
  188. - "elf-NetBSD-x86_64-echo": [
  189. + b"elf-NetBSD-x86_64-echo": [
  190. # TODO: soft, no elf
  191. - (COMMON_PLAIN, [
  192. - "ELF 64-bit LSB shared object, x86-64, version 1 (SYSV)",
  193. - "ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /libexec/ld.elf_so, for NetBSD 8.0, not stripped",
  194. - ]),
  195. - (COMMON_MIME, [
  196. - "application/x-pie-executable",
  197. - "application/x-sharedlib",
  198. - ]),
  199. - ({"check_elf": False}, [
  200. - "ELF 64-bit LSB shared object, x86-64, version 1 (SYSV)",
  201. - ]),
  202. + (
  203. + COMMON_PLAIN,
  204. + [
  205. + "ELF 64-bit LSB shared object, x86-64, version 1 (SYSV)",
  206. + "ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /libexec/ld.elf_so, for NetBSD 8.0, not stripped",
  207. + ],
  208. + ),
  209. + (
  210. + COMMON_MIME,
  211. + [
  212. + "application/x-pie-executable",
  213. + "application/x-sharedlib",
  214. + ],
  215. + ),
  216. + (
  217. + [{"check_elf": False}],
  218. + [
  219. + "ELF 64-bit LSB shared object, x86-64, version 1 (SYSV)",
  220. + ],
  221. + ),
  222. # TODO: sometimes
  223. # "ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /libexec/ld.elf_so, for NetBSD 8.0, not stripped",
  224. -
  225. (NO_SOFT, ["data"]),
  226. ],
  227. - "test.txt": [
  228. + b"text.txt": [
  229. (COMMON_MIME, ["text/plain"]),
  230. (COMMON_PLAIN, ["ASCII text"]),
  231. - ({"mime_encoding": True}, [
  232. - "us-ascii",
  233. - ]),
  234. + (
  235. + [{"mime_encoding": True}],
  236. + [
  237. + "us-ascii",
  238. + ],
  239. + ),
  240. (NO_SOFT, ["ASCII text"]),
  241. ],
  242. - "text-iso8859-1.txt": [
  243. - ({"mime_encoding": True}, [
  244. - "iso-8859-1",
  245. - ]),
  246. + b"text-iso8859-1.txt": [
  247. + (
  248. + [{"mime_encoding": True}],
  249. + [
  250. + "iso-8859-1",
  251. + ],
  252. + ),
  253. ],
  254. b"\xce\xbb": [
  255. (COMMON_MIME, ["text/plain"]),
  256. ],
  257. - "b\xce\xbb".decode("utf-8"): [
  258. - (COMMON_MIME, ["text/plain"]),
  259. + b"name_use.jpg": [
  260. + ([{"extension": True}], ["jpeg/jpg/jpe/jfif"]),
  261. + ],
  262. + b"keep-going.jpg": [
  263. + (COMMON_MIME, ["image/jpeg"]),
  264. + (
  265. + [{"mime": True, "keep_going": True}],
  266. + [
  267. + "image/jpeg\\012- application/octet-stream",
  268. + ],
  269. + ),
  270. + ],
  271. + b"../../magic/loader.py": [
  272. + (
  273. + COMMON_MIME,
  274. + [
  275. + "text/x-python",
  276. + "text/x-script.python",
  277. + ],
  278. + )
  279. ],
  280. - "name_use.jpg": [
  281. - ({"extension": True}, [
  282. - "jpeg/jpg/jpe/jfif"
  283. - ]),
  284. - ],
  285. - "keep-going.jpg": [
  286. - (COMMON_MIME, [
  287. - "image/jpeg"
  288. - ]),
  289. - ({"mime": True, "keep_going": True}, [
  290. - "image/jpeg\\012- application/octet-stream",
  291. - ])
  292. - ],
  293. - "test.py": [
  294. - (COMMON_MIME, [
  295. - "text/x-python",
  296. - "text/x-script.python",
  297. - ])
  298. - ]
  299. }
  300. +
  301. class MagicTest(unittest.TestCase):
  302. TESTDATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "testdata"))
  303. @@ -165,7 +188,6 @@
  304. def test_fs_encoding(self):
  305. self.assertEqual("utf-8", sys.getfilesystemencoding().lower())
  306. -
  307. def test_from_file_str_and_bytes(self):
  308. filename = os.path.join(self.TESTDATA_DIR, "test.pdf")
  309. @@ -174,7 +196,6 @@
  310. "application/pdf", magic.from_file(filename.encode("utf-8"), mime=True)
  311. )
  312. -
  313. def test_all_cases(self):
  314. # TODO:
  315. # * MAGIC_EXTENSION not supported
  316. @@ -184,21 +205,24 @@
  317. shutil.copyfile(os.path.join(MagicTest.TESTDATA_DIR, "lambda"), dest)
  318. os.environ["TZ"] = "UTC"
  319. try:
  320. - for file_name, cases in CASES:
  321. - filename = os.path.join(self.TESTDATA_DIR, file_name)
  322. - for flags, outputs in cases:
  323. - m = magic.Magic(**flags)
  324. - with open(filename) as f:
  325. - self.assertIn(m.from_descriptor(f.fileno()), outputs)
  326. -
  327. - self.assertIn(m.from_file(filename), outputs)
  328. -
  329. - fname_bytes = filename.encode("utf-8")
  330. - self.assertIn(m.from_file(fname_bytes), outputs)
  331. -
  332. - with open(file_name, "rb") as f:
  333. - buf_result = m.from_buffer(f.read(1024))
  334. - self.assertIn(buf_result, outputs)
  335. + for filename, cases in CASES.items():
  336. + filename = os.path.join(self.TESTDATA_DIR.encode("utf-8"), filename)
  337. + print("test case ", filename, file=sys.stderr)
  338. + for flag_variants, outputs in cases:
  339. + for flags in flag_variants:
  340. + print("flags", flags, file=sys.stderr)
  341. + m = magic.Magic(**flags)
  342. + with open(filename) as f:
  343. + self.assertIn(m.from_descriptor(f.fileno()), outputs)
  344. +
  345. + self.assertIn(m.from_file(filename), outputs)
  346. +
  347. + fname_str = filename.decode("utf-8")
  348. + self.assertIn(m.from_file(fname_str), outputs)
  349. +
  350. + with open(filename, "rb") as f:
  351. + buf_result = m.from_buffer(f.read(1024))
  352. + self.assertIn(buf_result, outputs)
  353. finally:
  354. del os.environ["TZ"]
  355. os.unlink(dest)
  356. @@ -222,7 +246,6 @@
  357. else:
  358. raise unittest.SkipTest("Magic file doesn't return expected type.")
  359. -
  360. def test_errors(self):
  361. m = magic.Magic()
  362. self.assertRaises(IOError, m.from_file, "nonexistent")
  363. @@ -233,7 +256,6 @@
  364. finally:
  365. del os.environ["MAGIC"]
  366. -
  367. def test_rethrow(self):
  368. old = magic.magic_buffer
  369. try: