polyfile-weave 0.5.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of polyfile-weave might be problematic. Click here for more details.

Files changed (585) hide show
  1. polyfile/__init__.py +15 -0
  2. polyfile/__main__.py +394 -0
  3. polyfile/arithmetic.py +27 -0
  4. polyfile/ast.py +114 -0
  5. polyfile/debugger.py +1039 -0
  6. polyfile/expressions.py +346 -0
  7. polyfile/fileutils.py +343 -0
  8. polyfile/html.py +135 -0
  9. polyfile/http/__init__.py +1 -0
  10. polyfile/http/defacto.py +37 -0
  11. polyfile/http/deprecated.py +51 -0
  12. polyfile/http/experimental.py +67 -0
  13. polyfile/http/http_11.py +548 -0
  14. polyfile/http/matcher.py +37 -0
  15. polyfile/http/structured_headers.py +48 -0
  16. polyfile/iterators.py +72 -0
  17. polyfile/jpeg.py +24 -0
  18. polyfile/kaitai/__init__.py +0 -0
  19. polyfile/kaitai/compiler.py +156 -0
  20. polyfile/kaitai/parser.py +312 -0
  21. polyfile/kaitai/parsers/__init__.py +0 -0
  22. polyfile/kaitai/parsers/aix_utmp.py +116 -0
  23. polyfile/kaitai/parsers/allegro_dat.py +367 -0
  24. polyfile/kaitai/parsers/andes_firmware.py +64 -0
  25. polyfile/kaitai/parsers/android_bootldr_asus.py +105 -0
  26. polyfile/kaitai/parsers/android_bootldr_huawei.py +181 -0
  27. polyfile/kaitai/parsers/android_bootldr_qcom.py +217 -0
  28. polyfile/kaitai/parsers/android_dto.py +138 -0
  29. polyfile/kaitai/parsers/android_img.py +319 -0
  30. polyfile/kaitai/parsers/android_nanoapp_header.py +83 -0
  31. polyfile/kaitai/parsers/android_opengl_shaders_cache.py +151 -0
  32. polyfile/kaitai/parsers/android_sparse.py +237 -0
  33. polyfile/kaitai/parsers/android_super.py +401 -0
  34. polyfile/kaitai/parsers/apm_partition_table.py +196 -0
  35. polyfile/kaitai/parsers/apple_single_double.py +180 -0
  36. polyfile/kaitai/parsers/asn1_der.py +235 -0
  37. polyfile/kaitai/parsers/au.py +138 -0
  38. polyfile/kaitai/parsers/avantes_roh60.py +112 -0
  39. polyfile/kaitai/parsers/avi.py +296 -0
  40. polyfile/kaitai/parsers/bcd.py +111 -0
  41. polyfile/kaitai/parsers/bitcoin_transaction.py +210 -0
  42. polyfile/kaitai/parsers/blender_blend.py +334 -0
  43. polyfile/kaitai/parsers/bmp.py +780 -0
  44. polyfile/kaitai/parsers/bson.py +411 -0
  45. polyfile/kaitai/parsers/btrfs_stream.py +318 -0
  46. polyfile/kaitai/parsers/bytes_with_io.py +27 -0
  47. polyfile/kaitai/parsers/chrome_pak.py +194 -0
  48. polyfile/kaitai/parsers/code_6502.py +456 -0
  49. polyfile/kaitai/parsers/compressed_resource.py +217 -0
  50. polyfile/kaitai/parsers/cpio_old_le.py +154 -0
  51. polyfile/kaitai/parsers/cramfs.py +344 -0
  52. polyfile/kaitai/parsers/creative_voice_file.py +342 -0
  53. polyfile/kaitai/parsers/dbf.py +274 -0
  54. polyfile/kaitai/parsers/dcmp_0.py +664 -0
  55. polyfile/kaitai/parsers/dcmp_1.py +422 -0
  56. polyfile/kaitai/parsers/dcmp_2.py +312 -0
  57. polyfile/kaitai/parsers/dcmp_variable_length_integer.py +66 -0
  58. polyfile/kaitai/parsers/dex.py +1086 -0
  59. polyfile/kaitai/parsers/dicom.py +4370 -0
  60. polyfile/kaitai/parsers/dime_message.py +201 -0
  61. polyfile/kaitai/parsers/dns_packet.py +569 -0
  62. polyfile/kaitai/parsers/doom_wad.py +654 -0
  63. polyfile/kaitai/parsers/dos_datetime.py +191 -0
  64. polyfile/kaitai/parsers/dos_mz.py +172 -0
  65. polyfile/kaitai/parsers/ds_store.py +513 -0
  66. polyfile/kaitai/parsers/dtb.py +310 -0
  67. polyfile/kaitai/parsers/dune_2_pak.py +126 -0
  68. polyfile/kaitai/parsers/edid.py +472 -0
  69. polyfile/kaitai/parsers/efivar_signature_list.py +331 -0
  70. polyfile/kaitai/parsers/elf.py +2482 -0
  71. polyfile/kaitai/parsers/ethernet_frame.py +114 -0
  72. polyfile/kaitai/parsers/exif.py +723 -0
  73. polyfile/kaitai/parsers/ext2.py +537 -0
  74. polyfile/kaitai/parsers/fallout2_dat.py +187 -0
  75. polyfile/kaitai/parsers/fallout_dat.py +156 -0
  76. polyfile/kaitai/parsers/fasttracker_xm_module.py +558 -0
  77. polyfile/kaitai/parsers/ftl_dat.py +90 -0
  78. polyfile/kaitai/parsers/genmidi_op2.py +161 -0
  79. polyfile/kaitai/parsers/gettext_mo.py +541 -0
  80. polyfile/kaitai/parsers/gif.py +492 -0
  81. polyfile/kaitai/parsers/gimp_brush.py +244 -0
  82. polyfile/kaitai/parsers/glibc_utmp.py +114 -0
  83. polyfile/kaitai/parsers/gltf_binary.py +132 -0
  84. polyfile/kaitai/parsers/google_protobuf.py +151 -0
  85. polyfile/kaitai/parsers/gpt_partition_table.py +175 -0
  86. polyfile/kaitai/parsers/gran_turismo_vol.py +140 -0
  87. polyfile/kaitai/parsers/grub2_font.py +337 -0
  88. polyfile/kaitai/parsers/gzip.py +232 -0
  89. polyfile/kaitai/parsers/hashcat_restore.py +60 -0
  90. polyfile/kaitai/parsers/hccap.py +111 -0
  91. polyfile/kaitai/parsers/hccapx.py +103 -0
  92. polyfile/kaitai/parsers/heaps_pak.py +177 -0
  93. polyfile/kaitai/parsers/heroes_of_might_and_magic_agg.py +116 -0
  94. polyfile/kaitai/parsers/heroes_of_might_and_magic_bmp.py +34 -0
  95. polyfile/kaitai/parsers/icmp_packet.py +136 -0
  96. polyfile/kaitai/parsers/ico.py +129 -0
  97. polyfile/kaitai/parsers/id3v1_1.py +220 -0
  98. polyfile/kaitai/parsers/id3v2_3.py +324 -0
  99. polyfile/kaitai/parsers/id3v2_4.py +423 -0
  100. polyfile/kaitai/parsers/ines.py +282 -0
  101. polyfile/kaitai/parsers/ipv4_packet.py +158 -0
  102. polyfile/kaitai/parsers/ipv6_packet.py +55 -0
  103. polyfile/kaitai/parsers/iso9660.py +544 -0
  104. polyfile/kaitai/parsers/java_class.py +1113 -0
  105. polyfile/kaitai/parsers/jpeg.py +361 -0
  106. polyfile/kaitai/parsers/luks.py +149 -0
  107. polyfile/kaitai/parsers/lzh.py +165 -0
  108. polyfile/kaitai/parsers/mac_os_resource_snd.py +493 -0
  109. polyfile/kaitai/parsers/mach_o.py +3033 -0
  110. polyfile/kaitai/parsers/mach_o_fat.py +92 -0
  111. polyfile/kaitai/parsers/magicavoxel_vox.py +391 -0
  112. polyfile/kaitai/parsers/manifest.json +1 -0
  113. polyfile/kaitai/parsers/mbr_partition_table.py +119 -0
  114. polyfile/kaitai/parsers/mcap.py +1015 -0
  115. polyfile/kaitai/parsers/microsoft_cfb.py +293 -0
  116. polyfile/kaitai/parsers/microsoft_network_monitor_v2.py +309 -0
  117. polyfile/kaitai/parsers/microsoft_pe.py +765 -0
  118. polyfile/kaitai/parsers/mifare_classic.py +706 -0
  119. polyfile/kaitai/parsers/minecraft_nbt.py +449 -0
  120. polyfile/kaitai/parsers/monomakh_sapr_chg.py +69 -0
  121. polyfile/kaitai/parsers/mozilla_mar.py +239 -0
  122. polyfile/kaitai/parsers/mp4.py +333 -0
  123. polyfile/kaitai/parsers/msgpack.py +467 -0
  124. polyfile/kaitai/parsers/nitf.py +1189 -0
  125. polyfile/kaitai/parsers/nt_mdt_pal.py +155 -0
  126. polyfile/kaitai/parsers/ogg.py +118 -0
  127. polyfile/kaitai/parsers/openpgp_message.py +993 -0
  128. polyfile/kaitai/parsers/packet_ppi.py +515 -0
  129. polyfile/kaitai/parsers/pcap.py +344 -0
  130. polyfile/kaitai/parsers/pcf_font.py +506 -0
  131. polyfile/kaitai/parsers/pcx.py +195 -0
  132. polyfile/kaitai/parsers/pcx_dcx.py +79 -0
  133. polyfile/kaitai/parsers/phar_without_stub.py +399 -0
  134. polyfile/kaitai/parsers/php_serialized_value.py +505 -0
  135. polyfile/kaitai/parsers/png.py +721 -0
  136. polyfile/kaitai/parsers/protocol_body.py +260 -0
  137. polyfile/kaitai/parsers/psx_tim.py +104 -0
  138. polyfile/kaitai/parsers/python_pickle.py +718 -0
  139. polyfile/kaitai/parsers/python_pyc_27.py +510 -0
  140. polyfile/kaitai/parsers/quake_mdl.py +441 -0
  141. polyfile/kaitai/parsers/quake_pak.py +112 -0
  142. polyfile/kaitai/parsers/quicktime_mov.py +634 -0
  143. polyfile/kaitai/parsers/rar.py +265 -0
  144. polyfile/kaitai/parsers/regf.py +569 -0
  145. polyfile/kaitai/parsers/renderware_binary_stream.py +877 -0
  146. polyfile/kaitai/parsers/resource_fork.py +611 -0
  147. polyfile/kaitai/parsers/respack.py +57 -0
  148. polyfile/kaitai/parsers/riff.py +409 -0
  149. polyfile/kaitai/parsers/rpm.py +964 -0
  150. polyfile/kaitai/parsers/rtcp_payload.py +579 -0
  151. polyfile/kaitai/parsers/rtp_packet.py +150 -0
  152. polyfile/kaitai/parsers/rtpdump.py +115 -0
  153. polyfile/kaitai/parsers/ruby_marshal.py +423 -0
  154. polyfile/kaitai/parsers/s3m.py +493 -0
  155. polyfile/kaitai/parsers/saints_row_2_vpp_pc.py +254 -0
  156. polyfile/kaitai/parsers/shapefile_index.py +174 -0
  157. polyfile/kaitai/parsers/shapefile_main.py +893 -0
  158. polyfile/kaitai/parsers/some_ip.py +209 -0
  159. polyfile/kaitai/parsers/some_ip_container.py +37 -0
  160. polyfile/kaitai/parsers/some_ip_sd.py +86 -0
  161. polyfile/kaitai/parsers/some_ip_sd_entries.py +160 -0
  162. polyfile/kaitai/parsers/some_ip_sd_options.py +374 -0
  163. polyfile/kaitai/parsers/specpr.py +404 -0
  164. polyfile/kaitai/parsers/sqlite3.py +472 -0
  165. polyfile/kaitai/parsers/ssh_public_key.py +252 -0
  166. polyfile/kaitai/parsers/standard_midi_file.py +390 -0
  167. polyfile/kaitai/parsers/stl.py +111 -0
  168. polyfile/kaitai/parsers/sudoers_ts.py +201 -0
  169. polyfile/kaitai/parsers/swf.py +406 -0
  170. polyfile/kaitai/parsers/systemd_journal.py +361 -0
  171. polyfile/kaitai/parsers/tcp_segment.py +57 -0
  172. polyfile/kaitai/parsers/tga.py +213 -0
  173. polyfile/kaitai/parsers/tls_client_hello.py +293 -0
  174. polyfile/kaitai/parsers/tr_dos_image.py +322 -0
  175. polyfile/kaitai/parsers/tsm.py +198 -0
  176. polyfile/kaitai/parsers/ttf.py +1847 -0
  177. polyfile/kaitai/parsers/udp_datagram.py +42 -0
  178. polyfile/kaitai/parsers/uefi_te.py +236 -0
  179. polyfile/kaitai/parsers/uimage.py +198 -0
  180. polyfile/kaitai/parsers/utf8_string.py +137 -0
  181. polyfile/kaitai/parsers/vfat.py +410 -0
  182. polyfile/kaitai/parsers/vlq_base128_be.py +104 -0
  183. polyfile/kaitai/parsers/vlq_base128_le.py +129 -0
  184. polyfile/kaitai/parsers/vmware_vmdk.py +167 -0
  185. polyfile/kaitai/parsers/vp8_ivf.py +112 -0
  186. polyfile/kaitai/parsers/warcraft_2_pud.py +423 -0
  187. polyfile/kaitai/parsers/wav.py +1014 -0
  188. polyfile/kaitai/parsers/websocket.py +167 -0
  189. polyfile/kaitai/parsers/windows_evt_log.py +304 -0
  190. polyfile/kaitai/parsers/windows_lnk_file.py +467 -0
  191. polyfile/kaitai/parsers/windows_minidump.py +575 -0
  192. polyfile/kaitai/parsers/windows_resource_file.py +243 -0
  193. polyfile/kaitai/parsers/windows_shell_items.py +190 -0
  194. polyfile/kaitai/parsers/windows_systemtime.py +52 -0
  195. polyfile/kaitai/parsers/wmf.py +502 -0
  196. polyfile/kaitai/parsers/xar.py +181 -0
  197. polyfile/kaitai/parsers/xwd.py +189 -0
  198. polyfile/kaitai/parsers/zip.py +685 -0
  199. polyfile/kaitai/parsers/zisofs.py +158 -0
  200. polyfile/kaitai/parsers/zx_spectrum_tap.py +184 -0
  201. polyfile/kaitaimatcher.py +113 -0
  202. polyfile/languagematcher.py +217 -0
  203. polyfile/logger.py +135 -0
  204. polyfile/magic.py +2983 -0
  205. polyfile/magic_defs/COPYING +29 -0
  206. polyfile/magic_defs/__init__.py +0 -0
  207. polyfile/magic_defs/acorn +102 -0
  208. polyfile/magic_defs/adi +13 -0
  209. polyfile/magic_defs/adventure +122 -0
  210. polyfile/magic_defs/aes +29 -0
  211. polyfile/magic_defs/algol68 +35 -0
  212. polyfile/magic_defs/allegro +9 -0
  213. polyfile/magic_defs/alliant +18 -0
  214. polyfile/magic_defs/alpha +32 -0
  215. polyfile/magic_defs/amanda +12 -0
  216. polyfile/magic_defs/amigaos +218 -0
  217. polyfile/magic_defs/android +259 -0
  218. polyfile/magic_defs/animation +1197 -0
  219. polyfile/magic_defs/aout +46 -0
  220. polyfile/magic_defs/apache +28 -0
  221. polyfile/magic_defs/apl +7 -0
  222. polyfile/magic_defs/apple +773 -0
  223. polyfile/magic_defs/application +7 -0
  224. polyfile/magic_defs/applix +13 -0
  225. polyfile/magic_defs/apt +52 -0
  226. polyfile/magic_defs/archive +2586 -0
  227. polyfile/magic_defs/aria +38 -0
  228. polyfile/magic_defs/arm +50 -0
  229. polyfile/magic_defs/asf +132 -0
  230. polyfile/magic_defs/assembler +18 -0
  231. polyfile/magic_defs/asterix +18 -0
  232. polyfile/magic_defs/att3b +41 -0
  233. polyfile/magic_defs/audio +1291 -0
  234. polyfile/magic_defs/avm +33 -0
  235. polyfile/magic_defs/basis +18 -0
  236. polyfile/magic_defs/beetle +7 -0
  237. polyfile/magic_defs/ber +65 -0
  238. polyfile/magic_defs/bflt +14 -0
  239. polyfile/magic_defs/bhl +10 -0
  240. polyfile/magic_defs/bioinformatics +178 -0
  241. polyfile/magic_defs/biosig +154 -0
  242. polyfile/magic_defs/blackberry +8 -0
  243. polyfile/magic_defs/blcr +25 -0
  244. polyfile/magic_defs/blender +50 -0
  245. polyfile/magic_defs/blit +24 -0
  246. polyfile/magic_defs/bm +10 -0
  247. polyfile/magic_defs/bout +11 -0
  248. polyfile/magic_defs/bsdi +33 -0
  249. polyfile/magic_defs/bsi +10 -0
  250. polyfile/magic_defs/btsnoop +13 -0
  251. polyfile/magic_defs/burp +7 -0
  252. polyfile/magic_defs/bytecode +41 -0
  253. polyfile/magic_defs/c-lang +110 -0
  254. polyfile/magic_defs/c64 +531 -0
  255. polyfile/magic_defs/cad +437 -0
  256. polyfile/magic_defs/cafebabe +107 -0
  257. polyfile/magic_defs/cbor +21 -0
  258. polyfile/magic_defs/ccf +14 -0
  259. polyfile/magic_defs/cddb +12 -0
  260. polyfile/magic_defs/chord +15 -0
  261. polyfile/magic_defs/cisco +12 -0
  262. polyfile/magic_defs/citrus +12 -0
  263. polyfile/magic_defs/clarion +27 -0
  264. polyfile/magic_defs/claris +48 -0
  265. polyfile/magic_defs/clipper +65 -0
  266. polyfile/magic_defs/clojure +30 -0
  267. polyfile/magic_defs/coff +98 -0
  268. polyfile/magic_defs/commands +201 -0
  269. polyfile/magic_defs/communications +22 -0
  270. polyfile/magic_defs/compress +461 -0
  271. polyfile/magic_defs/console +1213 -0
  272. polyfile/magic_defs/convex +69 -0
  273. polyfile/magic_defs/coverage +91 -0
  274. polyfile/magic_defs/cracklib +14 -0
  275. polyfile/magic_defs/crypto +31 -0
  276. polyfile/magic_defs/csv +8 -0
  277. polyfile/magic_defs/ctags +6 -0
  278. polyfile/magic_defs/ctf +23 -0
  279. polyfile/magic_defs/cubemap +8 -0
  280. polyfile/magic_defs/cups +56 -0
  281. polyfile/magic_defs/dact +11 -0
  282. polyfile/magic_defs/database +886 -0
  283. polyfile/magic_defs/dataone +47 -0
  284. polyfile/magic_defs/dbpf +15 -0
  285. polyfile/magic_defs/der +146 -0
  286. polyfile/magic_defs/diamond +12 -0
  287. polyfile/magic_defs/dif +33 -0
  288. polyfile/magic_defs/diff +41 -0
  289. polyfile/magic_defs/digital +59 -0
  290. polyfile/magic_defs/dolby +69 -0
  291. polyfile/magic_defs/dsf +25 -0
  292. polyfile/magic_defs/dump +96 -0
  293. polyfile/magic_defs/dwarfs +45 -0
  294. polyfile/magic_defs/dyadic +61 -0
  295. polyfile/magic_defs/ebml +8 -0
  296. polyfile/magic_defs/edid +11 -0
  297. polyfile/magic_defs/editors +43 -0
  298. polyfile/magic_defs/efi +15 -0
  299. polyfile/magic_defs/elf +379 -0
  300. polyfile/magic_defs/encore +22 -0
  301. polyfile/magic_defs/epoc +62 -0
  302. polyfile/magic_defs/erlang +21 -0
  303. polyfile/magic_defs/espressif +57 -0
  304. polyfile/magic_defs/esri +28 -0
  305. polyfile/magic_defs/etf +33 -0
  306. polyfile/magic_defs/fcs +9 -0
  307. polyfile/magic_defs/filesystems +2694 -0
  308. polyfile/magic_defs/finger +16 -0
  309. polyfile/magic_defs/firmware +133 -0
  310. polyfile/magic_defs/flash +62 -0
  311. polyfile/magic_defs/flif +36 -0
  312. polyfile/magic_defs/fonts +449 -0
  313. polyfile/magic_defs/forth +82 -0
  314. polyfile/magic_defs/fortran +9 -0
  315. polyfile/magic_defs/frame +62 -0
  316. polyfile/magic_defs/freebsd +164 -0
  317. polyfile/magic_defs/fsav +128 -0
  318. polyfile/magic_defs/fusecompress +12 -0
  319. polyfile/magic_defs/games +696 -0
  320. polyfile/magic_defs/gcc +17 -0
  321. polyfile/magic_defs/gconv +10 -0
  322. polyfile/magic_defs/gentoo +85 -0
  323. polyfile/magic_defs/geo +166 -0
  324. polyfile/magic_defs/geos +20 -0
  325. polyfile/magic_defs/gimp +77 -0
  326. polyfile/magic_defs/git +13 -0
  327. polyfile/magic_defs/glibc +21 -0
  328. polyfile/magic_defs/gnome +59 -0
  329. polyfile/magic_defs/gnu +173 -0
  330. polyfile/magic_defs/gnumeric +8 -0
  331. polyfile/magic_defs/gpt +240 -0
  332. polyfile/magic_defs/gpu +28 -0
  333. polyfile/magic_defs/grace +21 -0
  334. polyfile/magic_defs/graphviz +12 -0
  335. polyfile/magic_defs/gringotts +48 -0
  336. polyfile/magic_defs/guile +13 -0
  337. polyfile/magic_defs/hardware +12 -0
  338. polyfile/magic_defs/hitachi-sh +30 -0
  339. polyfile/magic_defs/hp +433 -0
  340. polyfile/magic_defs/human68k +26 -0
  341. polyfile/magic_defs/ibm370 +52 -0
  342. polyfile/magic_defs/ibm6000 +35 -0
  343. polyfile/magic_defs/icc +214 -0
  344. polyfile/magic_defs/iff +80 -0
  345. polyfile/magic_defs/images +4210 -0
  346. polyfile/magic_defs/inform +9 -0
  347. polyfile/magic_defs/intel +310 -0
  348. polyfile/magic_defs/interleaf +9 -0
  349. polyfile/magic_defs/island +10 -0
  350. polyfile/magic_defs/ispell +63 -0
  351. polyfile/magic_defs/isz +15 -0
  352. polyfile/magic_defs/java +52 -0
  353. polyfile/magic_defs/javascript +171 -0
  354. polyfile/magic_defs/jpeg +252 -0
  355. polyfile/magic_defs/json +8 -0
  356. polyfile/magic_defs/karma +9 -0
  357. polyfile/magic_defs/kde +11 -0
  358. polyfile/magic_defs/keepass +20 -0
  359. polyfile/magic_defs/kerberos +45 -0
  360. polyfile/magic_defs/kicad +85 -0
  361. polyfile/magic_defs/kml +34 -0
  362. polyfile/magic_defs/lammps +64 -0
  363. polyfile/magic_defs/lecter +6 -0
  364. polyfile/magic_defs/lex +12 -0
  365. polyfile/magic_defs/lif +50 -0
  366. polyfile/magic_defs/linux +557 -0
  367. polyfile/magic_defs/lisp +78 -0
  368. polyfile/magic_defs/llvm +22 -0
  369. polyfile/magic_defs/locoscript +12 -0
  370. polyfile/magic_defs/lua +31 -0
  371. polyfile/magic_defs/luks +126 -0
  372. polyfile/magic_defs/m4 +11 -0
  373. polyfile/magic_defs/mach +303 -0
  374. polyfile/magic_defs/macintosh +505 -0
  375. polyfile/magic_defs/macos +7 -0
  376. polyfile/magic_defs/magic +10 -0
  377. polyfile/magic_defs/magic.mgc +0 -0
  378. polyfile/magic_defs/mail.news +132 -0
  379. polyfile/magic_defs/make +21 -0
  380. polyfile/magic_defs/map +413 -0
  381. polyfile/magic_defs/maple +109 -0
  382. polyfile/magic_defs/marc21 +30 -0
  383. polyfile/magic_defs/mathcad +8 -0
  384. polyfile/magic_defs/mathematica +188 -0
  385. polyfile/magic_defs/matroska +17 -0
  386. polyfile/magic_defs/mcrypt +52 -0
  387. polyfile/magic_defs/measure +44 -0
  388. polyfile/magic_defs/mercurial +13 -0
  389. polyfile/magic_defs/metastore +8 -0
  390. polyfile/magic_defs/meteorological +53 -0
  391. polyfile/magic_defs/microfocus +21 -0
  392. polyfile/magic_defs/mime +9 -0
  393. polyfile/magic_defs/mips +120 -0
  394. polyfile/magic_defs/mirage +8 -0
  395. polyfile/magic_defs/misctools +140 -0
  396. polyfile/magic_defs/mkid +11 -0
  397. polyfile/magic_defs/mlssa +8 -0
  398. polyfile/magic_defs/mmdf +6 -0
  399. polyfile/magic_defs/modem +92 -0
  400. polyfile/magic_defs/modulefile +9 -0
  401. polyfile/magic_defs/motorola +71 -0
  402. polyfile/magic_defs/mozilla +37 -0
  403. polyfile/magic_defs/msdos +2304 -0
  404. polyfile/magic_defs/msooxml +68 -0
  405. polyfile/magic_defs/msvc +222 -0
  406. polyfile/magic_defs/msx +309 -0
  407. polyfile/magic_defs/mup +24 -0
  408. polyfile/magic_defs/music +17 -0
  409. polyfile/magic_defs/nasa +7 -0
  410. polyfile/magic_defs/natinst +24 -0
  411. polyfile/magic_defs/ncr +49 -0
  412. polyfile/magic_defs/neko +12 -0
  413. polyfile/magic_defs/netbsd +251 -0
  414. polyfile/magic_defs/netscape +26 -0
  415. polyfile/magic_defs/netware +11 -0
  416. polyfile/magic_defs/news +13 -0
  417. polyfile/magic_defs/nifty +202 -0
  418. polyfile/magic_defs/nim-lang +29 -0
  419. polyfile/magic_defs/nitpicker +14 -0
  420. polyfile/magic_defs/numpy +9 -0
  421. polyfile/magic_defs/oasis +12 -0
  422. polyfile/magic_defs/ocaml +14 -0
  423. polyfile/magic_defs/octave +6 -0
  424. polyfile/magic_defs/ole2compounddocs +760 -0
  425. polyfile/magic_defs/olf +98 -0
  426. polyfile/magic_defs/openfst +17 -0
  427. polyfile/magic_defs/opentimestamps +16 -0
  428. polyfile/magic_defs/oric +16 -0
  429. polyfile/magic_defs/os2 +186 -0
  430. polyfile/magic_defs/os400 +39 -0
  431. polyfile/magic_defs/os9 +80 -0
  432. polyfile/magic_defs/osf1 +10 -0
  433. polyfile/magic_defs/palm +156 -0
  434. polyfile/magic_defs/parix +13 -0
  435. polyfile/magic_defs/parrot +22 -0
  436. polyfile/magic_defs/pascal +39 -0
  437. polyfile/magic_defs/pbf +11 -0
  438. polyfile/magic_defs/pbm +8 -0
  439. polyfile/magic_defs/pc88 +24 -0
  440. polyfile/magic_defs/pc98 +77 -0
  441. polyfile/magic_defs/pci_ids +116 -0
  442. polyfile/magic_defs/pcjr +8 -0
  443. polyfile/magic_defs/pdf +51 -0
  444. polyfile/magic_defs/pdp +42 -0
  445. polyfile/magic_defs/perl +100 -0
  446. polyfile/magic_defs/pgf +52 -0
  447. polyfile/magic_defs/pgp +581 -0
  448. polyfile/magic_defs/pgp-binary-keys +388 -0
  449. polyfile/magic_defs/pkgadd +7 -0
  450. polyfile/magic_defs/plan9 +25 -0
  451. polyfile/magic_defs/playdate +57 -0
  452. polyfile/magic_defs/plus5 +18 -0
  453. polyfile/magic_defs/pmem +46 -0
  454. polyfile/magic_defs/polyfile_zip +5 -0
  455. polyfile/magic_defs/polyml +23 -0
  456. polyfile/magic_defs/printer +269 -0
  457. polyfile/magic_defs/project +10 -0
  458. polyfile/magic_defs/psdbms +14 -0
  459. polyfile/magic_defs/psl +14 -0
  460. polyfile/magic_defs/pulsar +13 -0
  461. polyfile/magic_defs/puzzle +17 -0
  462. polyfile/magic_defs/pwsafe +14 -0
  463. polyfile/magic_defs/pyramid +12 -0
  464. polyfile/magic_defs/python +305 -0
  465. polyfile/magic_defs/qt +30 -0
  466. polyfile/magic_defs/revision +66 -0
  467. polyfile/magic_defs/riff +840 -0
  468. polyfile/magic_defs/rinex +44 -0
  469. polyfile/magic_defs/ringdove +45 -0
  470. polyfile/magic_defs/rpi +52 -0
  471. polyfile/magic_defs/rpm +45 -0
  472. polyfile/magic_defs/rpmsg +7 -0
  473. polyfile/magic_defs/rst +11 -0
  474. polyfile/magic_defs/rtf +94 -0
  475. polyfile/magic_defs/ruby +55 -0
  476. polyfile/magic_defs/rust +21 -0
  477. polyfile/magic_defs/sc +7 -0
  478. polyfile/magic_defs/sccs +24 -0
  479. polyfile/magic_defs/scientific +144 -0
  480. polyfile/magic_defs/securitycerts +6 -0
  481. polyfile/magic_defs/selinux +24 -0
  482. polyfile/magic_defs/sendmail +37 -0
  483. polyfile/magic_defs/sequent +42 -0
  484. polyfile/magic_defs/sereal +35 -0
  485. polyfile/magic_defs/sgi +144 -0
  486. polyfile/magic_defs/sgml +161 -0
  487. polyfile/magic_defs/sharc +23 -0
  488. polyfile/magic_defs/sinclair +40 -0
  489. polyfile/magic_defs/sisu +18 -0
  490. polyfile/magic_defs/sketch +6 -0
  491. polyfile/magic_defs/smalltalk +25 -0
  492. polyfile/magic_defs/smile +34 -0
  493. polyfile/magic_defs/sniffer +482 -0
  494. polyfile/magic_defs/softquad +40 -0
  495. polyfile/magic_defs/sosi +40 -0
  496. polyfile/magic_defs/spec +21 -0
  497. polyfile/magic_defs/spectrum +184 -0
  498. polyfile/magic_defs/sql +288 -0
  499. polyfile/magic_defs/ssh +39 -0
  500. polyfile/magic_defs/ssl +20 -0
  501. polyfile/magic_defs/statistics +45 -0
  502. polyfile/magic_defs/subtitle +38 -0
  503. polyfile/magic_defs/sun +141 -0
  504. polyfile/magic_defs/svf +5 -0
  505. polyfile/magic_defs/sylk +36 -0
  506. polyfile/magic_defs/symbos +42 -0
  507. polyfile/magic_defs/sysex +429 -0
  508. polyfile/magic_defs/tcl +29 -0
  509. polyfile/magic_defs/teapot +6 -0
  510. polyfile/magic_defs/terminfo +63 -0
  511. polyfile/magic_defs/tex +141 -0
  512. polyfile/magic_defs/tgif +7 -0
  513. polyfile/magic_defs/ti-8x +239 -0
  514. polyfile/magic_defs/timezone +42 -0
  515. polyfile/magic_defs/tplink +95 -0
  516. polyfile/magic_defs/troff +38 -0
  517. polyfile/magic_defs/tuxedo +8 -0
  518. polyfile/magic_defs/typeset +8 -0
  519. polyfile/magic_defs/uf2 +72 -0
  520. polyfile/magic_defs/unicode +15 -0
  521. polyfile/magic_defs/unisig +12 -0
  522. polyfile/magic_defs/unknown +34 -0
  523. polyfile/magic_defs/usd +21 -0
  524. polyfile/magic_defs/uterus +16 -0
  525. polyfile/magic_defs/uuencode +28 -0
  526. polyfile/magic_defs/vacuum-cleaner +54 -0
  527. polyfile/magic_defs/varied.out +46 -0
  528. polyfile/magic_defs/varied.script +21 -0
  529. polyfile/magic_defs/vax +32 -0
  530. polyfile/magic_defs/vicar +17 -0
  531. polyfile/magic_defs/virtual +307 -0
  532. polyfile/magic_defs/virtutech +12 -0
  533. polyfile/magic_defs/visx +32 -0
  534. polyfile/magic_defs/vms +30 -0
  535. polyfile/magic_defs/vmware +6 -0
  536. polyfile/magic_defs/vorbis +155 -0
  537. polyfile/magic_defs/vxl +14 -0
  538. polyfile/magic_defs/warc +16 -0
  539. polyfile/magic_defs/weak +16 -0
  540. polyfile/magic_defs/web +18 -0
  541. polyfile/magic_defs/webassembly +17 -0
  542. polyfile/magic_defs/windows +1811 -0
  543. polyfile/magic_defs/wireless +7 -0
  544. polyfile/magic_defs/wordprocessors +630 -0
  545. polyfile/magic_defs/wsdl +23 -0
  546. polyfile/magic_defs/x68000 +25 -0
  547. polyfile/magic_defs/xdelta +13 -0
  548. polyfile/magic_defs/xenix +106 -0
  549. polyfile/magic_defs/xilinx +58 -0
  550. polyfile/magic_defs/xo65 +37 -0
  551. polyfile/magic_defs/xwindows +43 -0
  552. polyfile/magic_defs/yara +17 -0
  553. polyfile/magic_defs/zfs +96 -0
  554. polyfile/magic_defs/zilog +12 -0
  555. polyfile/magic_defs/zip +126 -0
  556. polyfile/magic_defs/zyxel +17 -0
  557. polyfile/nes.py +144 -0
  558. polyfile/nitf.py +15 -0
  559. polyfile/pdf.py +1264 -0
  560. polyfile/pickles.py +45 -0
  561. polyfile/polyfile.py +409 -0
  562. polyfile/profiling.py +115 -0
  563. polyfile/repl.py +624 -0
  564. polyfile/search.py +310 -0
  565. polyfile/serialization.py +323 -0
  566. polyfile/structmatcher.py +46 -0
  567. polyfile/structs.py +281 -0
  568. polyfile/templates/download.js +162 -0
  569. polyfile/templates/hexdump.css +268 -0
  570. polyfile/templates/hexdump.js +756 -0
  571. polyfile/templates/jquery-3.4.1.min.js +2 -0
  572. polyfile/templates/template.html +119 -0
  573. polyfile/wildcards.py +62 -0
  574. polyfile/zipmatcher.py +183 -0
  575. polyfile_weave-0.5.5.dist-info/METADATA +173 -0
  576. polyfile_weave-0.5.5.dist-info/RECORD +585 -0
  577. polyfile_weave-0.5.5.dist-info/WHEEL +5 -0
  578. polyfile_weave-0.5.5.dist-info/entry_points.txt +2 -0
  579. polyfile_weave-0.5.5.dist-info/licenses/LICENSE +202 -0
  580. polyfile_weave-0.5.5.dist-info/top_level.txt +2 -0
  581. polymerge/__init__.py +1 -0
  582. polymerge/__main__.py +296 -0
  583. polymerge/cfg.py +127 -0
  584. polymerge/polymerge.py +227 -0
  585. polymerge/polytracker.py +190 -0
polyfile/__init__.py ADDED
@@ -0,0 +1,15 @@
1
+ from . import (
2
+ nes,
3
+ pdf,
4
+ jpeg,
5
+ zipmatcher,
6
+ nitf,
7
+ http,
8
+ kaitaimatcher,
9
+ languagematcher,
10
+ pickles,
11
+ polyfile
12
+ )
13
+
14
+ from .__main__ import main
15
+ from .polyfile import __version__, InvalidMatch, Match, Matcher, Parser, PARSERS, register_parser, Submatch
polyfile/__main__.py ADDED
@@ -0,0 +1,394 @@
1
+ import argparse
2
+ from contextlib import ExitStack
3
+ import json
4
+ import logging
5
+ import re
6
+ import signal
7
+ import sys
8
+ from textwrap import dedent
9
+ from typing import ContextManager, Optional, TextIO
10
+
11
+ from . import html
12
+ from . import logger
13
+ from .fileutils import PathOrStdin, PathOrStdout
14
+ from .magic import MagicMatcher
15
+ from .debugger import Debugger
16
+ from .polyfile import __version__, Analyzer
17
+ from .repl import ExitREPL
18
+
19
+
20
+ log = logger.getStatusLogger("polyfile")
21
+
22
+
23
+ class SIGTERMHandler:
24
+ def __init__(self):
25
+ self.terminated = False
26
+ signal.signal(signal.SIGTERM, self.sigterm_handler)
27
+
28
+ def sigterm_handler(self, signum, frame):
29
+ sys.stderr.flush()
30
+ sys.stderr.write('\n\nCaught SIGTERM. Exiting gracefully, and dumping partial results...\n')
31
+ self.terminated = True
32
+
33
+
34
+ class KeyboardInterruptHandler:
35
+ def __enter__(self):
36
+ pass
37
+
38
+ def __exit__(self, exc_type, exc_val, exc_tb):
39
+ if isinstance(exc_val, KeyboardInterrupt):
40
+ try:
41
+ sys.stdout.flush()
42
+ sys.stderr.flush()
43
+ sys.stderr.write("\n\nCaught keyboard interrupt.\n")
44
+ if not sys.stderr.isatty() or not sys.stdin.isatty():
45
+ sys.exit(128 + 15)
46
+ while True:
47
+ sys.stderr.write("Would you like PolyFile to output its current progress? [Yn] ")
48
+ result = input()
49
+ if not result or result.lower() == 'y':
50
+ return True
51
+ elif result and result.lower() == 'n':
52
+ sys.exit(0)
53
+ except KeyboardInterrupt:
54
+ sys.exit(128 + signal.SIGINT)
55
+ else:
56
+ return exc_type is None
57
+
58
+
59
+ class FormatOutput:
60
+ valid_formats = ("mime", "html", "json", "sbud", "explain")
61
+ default_format = "file"
62
+
63
+ def __init__(self, output_format: Optional[str] = None, output_path: Optional[str] = None):
64
+ if output_format is None:
65
+ output_format = self.default_format
66
+ self.output_format: str = output_format
67
+ self.output_path: Optional[str] = output_path
68
+
69
+ @property
70
+ def output_to_stdout(self) -> bool:
71
+ return self.output_path is None or self.output_path == "-"
72
+
73
+ @property
74
+ def output_stream(self) -> ContextManager[TextIO]:
75
+ if self.output_path is None:
76
+ return PathOrStdout("-")
77
+ else:
78
+ return PathOrStdout(self.output_path)
79
+
80
+ def __hash__(self):
81
+ return hash((self.output_format, self.output_path))
82
+
83
+ def __eq__(self, other):
84
+ return isinstance(other, FormatOutput) and other.output_format == self.output_format and other.output_path == self.output_path
85
+
86
+ def __str__(self):
87
+ return self.output_format
88
+
89
+ __repr__ = __str__
90
+
91
+
92
+ class ValidateOutput(argparse.Action):
93
+ @staticmethod
94
+ def add_output(args: argparse.Namespace, path: str):
95
+ if not hasattr(args, "format") or args.format is None:
96
+ setattr(args, "format", [])
97
+ if len(args.format) == 0:
98
+ args.format.append(FormatOutput(output_path=path))
99
+ return
100
+ existing_format: FormatOutput = args.format[-1]
101
+ if path != "-":
102
+ # make sure this path isn't already used
103
+ for output_format in args.format[:-1]:
104
+ if output_format.output_path == path:
105
+ raise ValueError(f"output path {path!r} cannot be used for both --format "
106
+ f"{output_format.output_format} and --format {existing_format.output_format}")
107
+ if existing_format.output_path is not None and existing_format.output_path != path:
108
+ args.format.append(FormatOutput(output_format=existing_format.output_format, output_path=path))
109
+ else:
110
+ existing_format.output_path = path
111
+
112
+ def __call__(self, parser, args, values, option_string=None):
113
+ ValidateOutput.add_output(args, values)
114
+
115
+
116
+ def main(argv=None):
117
+ parser = argparse.ArgumentParser(description='A utility to recursively map the structure of a file.',
118
+ formatter_class=argparse.RawTextHelpFormatter)
119
+ parser.add_argument('FILE', nargs='?', default='-',
120
+ help='the file to analyze; pass \'-\' or omit to read from STDIN')
121
+
122
+ parser.add_argument('--format', '-r', type=FormatOutput, action="append", choices=[
123
+ FormatOutput(f) for f in FormatOutput.valid_formats + ("json",)
124
+ ], help=dedent("""PolyFile's output format
125
+
126
+ Output formats are:
127
+ file ...... the detected formats associated with the file,
128
+ like the output of the `file` command
129
+ mime ...... the detected MIME types associated with the file,
130
+ like the output of the `file --mime-type` command
131
+ explain ... like 'mime', but adds a human-readable explanation
132
+ for why each MIME type matched
133
+ html ...... an interactive HTML-based hex viewer
134
+ json ...... a modified version of the SBUD format in JSON syntax
135
+ sbud ...... equivalent to 'json'
136
+
137
+ Multiple formats can be output at once:
138
+
139
+ polyfile INPUT_FILE -f mime -f json
140
+
141
+ Their output will be concatenated to STDOUT in the order that
142
+ they occur in the arguments.
143
+
144
+ To save each format to a separate file, see the `--output` argument.
145
+
146
+ If no format is specified, PolyFile defaults to `--format file`"""))
147
+
148
+ parser.add_argument('--output', '-o', action=ValidateOutput, type=str, # nargs=2,
149
+ # metavar=(f"{{{','.join(ValidateOutput.valid_outputs)}}}", "PATH"),
150
+ help=dedent("""an optional output path for `--format`
151
+
152
+ Each instance of `--output` applies to the previous instance
153
+ of the `--format` option.
154
+
155
+ For example:
156
+
157
+ polyfile INPUT_FILE --format html --output output.html \\
158
+ --format sbud --output output.json
159
+
160
+ will save HTML to to `output.html` and SBUD to `output.json`.
161
+ No two outputs can be directed at the same file path.
162
+
163
+ The path can be '-' for STDOUT.
164
+ If an `--output` is omitted for a format,
165
+ then it will implicitly be printed to STDOUT.
166
+ """))
167
+
168
+ parser.add_argument('--filetype', '-f', action='append',
169
+ help='explicitly match against the given filetype or filetype wildcard (default is to match '
170
+ 'against all filetypes)')
171
+
172
+ group = parser.add_mutually_exclusive_group()
173
+ group.add_argument('--list', '-l', action='store_true',
174
+ help='list the supported filetypes for the `--filetype` argument and exit')
175
+ group.add_argument('--html', '-t', action="append",
176
+ help=dedent("""path to write an interactive HTML file for exploring the PDF;
177
+ equivalent to `--format html --output HTML`"""))
178
+ group.add_argument("--explain", action="store_true", help="equivalent to `--format explain")
179
+ # parser.add_argument('--try-all-offsets', '-a', action='store_true',
180
+ # help='Search for a file match at every possible offset; this can be very slow for larger '
181
+ # 'files')
182
+ group.add_argument('--only-match-mime', '-I', action='store_true',
183
+ help=dedent(""""just print out the matching MIME types for the file, one on each line;
184
+ equivalent to `--format mime`"""))
185
+ parser.add_argument('--only-match', '-m', action='store_true',
186
+ help='do not attempt to parse known filetypes; only match against file magic')
187
+ parser.add_argument('--require-match', action='store_true', help='if no matches are found, exit with code 127')
188
+ parser.add_argument('--max-matches', type=int, default=None,
189
+ help='stop scanning after having found this many matches')
190
+ parser.add_argument('--debugger', '-db', action='store_true', help='drop into an interactive debugger for libmagic '
191
+ 'file definition matching and PolyFile parsing')
192
+ parser.add_argument('--eval-command', '-ex', type=str, action='append', help='execute the given debugger command')
193
+ parser.add_argument('--no-debug-python', action='store_true', help='by default, the `--debugger` option will break '
194
+ 'on custom matchers and prompt to debug using '
195
+ 'PDB. This option will suppress those prompts.')
196
+ verbosity_group = parser.add_mutually_exclusive_group()
197
+ verbosity_group.add_argument('--quiet', '-q', action='store_true', help='suppress all log output')
198
+ verbosity_group.add_argument('--debug', '-d', action='store_true', help='print debug information')
199
+ verbosity_group.add_argument('--trace', '-dd', action='store_true', help='print extra verbose debug information')
200
+
201
+ parser.add_argument('--version', '-v', action='store_true', help='print PolyFile\'s version information to STDERR')
202
+
203
+ group.add_argument('-dumpversion', action='store_true',
204
+ help='print PolyFile\'s raw version information to STDOUT and exit')
205
+
206
+ if argv is None:
207
+ argv = sys.argv
208
+
209
+ try:
210
+ args = parser.parse_args(argv[1:])
211
+ except ValueError as e:
212
+ parser.print_usage()
213
+ sys.stderr.write(f"polyfile: error: {e!s}\n")
214
+ exit(1)
215
+
216
+ if args.dumpversion:
217
+ print(__version__)
218
+ exit(0)
219
+
220
+ if args.eval_command and not args.debugger:
221
+ parser.print_usage()
222
+ sys.stderr.write("polyfile: error: the `--eval-command` argument can only be used in conjunction with "
223
+ "`--debugger`\n")
224
+ exit(1)
225
+
226
+ if args.list:
227
+ for mimetype in sorted(MagicMatcher.DEFAULT_INSTANCE.mimetypes):
228
+ print(mimetype)
229
+ exit(0)
230
+
231
+ if args.version:
232
+ sys.stderr.write(f"PolyFile version {__version__}\n")
233
+ if args.FILE == '-' and sys.stdin.isatty():
234
+ # No file argument was provided and it doesn't look like anything was piped into STDIN,
235
+ # so instead of blocking on STDIN just exit
236
+ exit(0)
237
+
238
+ if not hasattr(args, "format") or args.format is None or len(args.format) == 0:
239
+ setattr(args, "format", [])
240
+
241
+ if hasattr(args, "html") and args.html is not None:
242
+ for html_path in args.html:
243
+ args.format.append(FormatOutput(output_format="html"))
244
+ ValidateOutput.add_output(args, html_path)
245
+
246
+ if hasattr(args, "explain") and args.explain:
247
+ args.format.append(FormatOutput(output_format="explain"))
248
+
249
+ if args.only_match_mime:
250
+ args.format.append(FormatOutput(output_format="mime"))
251
+
252
+ if not args.format:
253
+ args.format.append(FormatOutput())
254
+
255
+ if args.quiet:
256
+ logger.setLevel(logging.CRITICAL)
257
+ elif args.trace:
258
+ logger.setLevel(logger.TRACE)
259
+ elif args.debug:
260
+ logger.setLevel(logging.DEBUG)
261
+ else:
262
+ logger.setLevel(logger.STATUS)
263
+
264
+ if args.filetype:
265
+ regex = r'|'.join(fr"({ f.replace('*', '.*').replace('?', '.?') })" for f in args.filetype)
266
+ matcher = re.compile(regex)
267
+ mimetypes = [mimetype for mimetype in MagicMatcher.DEFAULT_INSTANCE.mimetypes if matcher.fullmatch(mimetype)]
268
+ if not mimetypes:
269
+ log.error(f"Filetype argument(s) { args.filetype } did not match any known definitions!")
270
+ exit(1)
271
+ log.info(f"Only matching against these types: {', '.join(mimetypes)}")
272
+ magic_matcher: Optional[MagicMatcher] = MagicMatcher.DEFAULT_INSTANCE.only_match(mimetypes=mimetypes)
273
+ else:
274
+ magic_matcher = None
275
+
276
+ sigterm_handler = SIGTERMHandler()
277
+
278
+ try:
279
+ path_or_stdin = PathOrStdin(args.FILE)
280
+ except FileNotFoundError:
281
+ log.error(f"Cannot open {args.FILE!r} (No such file or directory)")
282
+ exit(1)
283
+ except KeyboardInterrupt:
284
+ # this will happen if the user presses ^C wile reading from STDIN
285
+ exit(1)
286
+ return # this is here because linters are dumb and will complain about the next line without it
287
+
288
+ with path_or_stdin as file_path, ExitStack() as stack:
289
+ if args.debugger:
290
+ debugger = Debugger(break_on_parsing=not args.no_debug_python)
291
+ if args.eval_command:
292
+ for ex in args.eval_command:
293
+ try:
294
+ debugger.before_prompt()
295
+ debugger.write(f"{debugger.repl_prompt}{ex}\n")
296
+ debugger.run_command(ex)
297
+ except KeyError:
298
+ exit(1)
299
+ except ExitREPL:
300
+ exit(0)
301
+ debugger.write("\n")
302
+ stack.enter_context(debugger)
303
+ elif args.no_debug_python:
304
+ log.warning("Ignoring `--no-debug-python`; it can only be used with the --debugger option.")
305
+
306
+ analyzer = Analyzer(file_path, parse=not args.only_match, magic_matcher=magic_matcher)
307
+
308
+ needs_sbud = any(output_format.output_format in {"html", "json", "sbud"} for output_format in args.format)
309
+ with KeyboardInterruptHandler():
310
+ # do we need to do a full match? if so, do that up front:
311
+ if needs_sbud:
312
+ if args.max_matches is None or args.max_matches > 0:
313
+ for match in analyzer.matches():
314
+ if sigterm_handler.terminated:
315
+ break
316
+ if match.parent is None:
317
+ if args.max_matches is not None and len(analyzer.matches_so_far) >= args.max_matches:
318
+ log.info(f"Found {args.max_matches} matches; stopping early")
319
+ break
320
+ if needs_sbud:
321
+ sbud = analyzer.sbud(matches=analyzer.matches_so_far)
322
+
323
+ if args.require_match and not analyzer.matches_so_far:
324
+ log.info("No matches found, exiting")
325
+ exit(127)
326
+
327
+ for output_format in args.format:
328
+ with output_format.output_stream as output:
329
+ if output_format.output_format == "file":
330
+ istty = sys.stderr.isatty() and output.isatty() and logging.root.level <= logging.INFO
331
+ lines = set()
332
+ with KeyboardInterruptHandler():
333
+ for match in analyzer.magic_matches():
334
+ line = str(match)
335
+ if line not in lines:
336
+ lines.add(line)
337
+ if istty:
338
+ log.clear_status()
339
+ output.write(f"{line}\n")
340
+ output.flush()
341
+ else:
342
+ output.write(f"{line}\n")
343
+ if istty:
344
+ log.clear_status()
345
+ elif output_format.output_format in ("mime", "explain"):
346
+ omm = sys.stderr.isatty() and output.isatty() and logging.root.level <= logging.INFO
347
+ if omm:
348
+ # figure out the longest MIME type so we can make sure the columns are aligned
349
+ longest_mimetype = max(len(mimetype) for mimetype in analyzer.magic_matcher.mimetypes)
350
+ found_match = False
351
+ with KeyboardInterruptHandler():
352
+ for mimetype, match in analyzer.mime_types():
353
+ found_match = True
354
+ if omm:
355
+ log.clear_status()
356
+ output.write(mimetype)
357
+ output.flush()
358
+ sys.stderr.write("." * (longest_mimetype - len(mimetype) + 1))
359
+ sys.stderr.write(str(match))
360
+ sys.stderr.flush()
361
+ output.write("\n")
362
+ output.flush()
363
+ else:
364
+ output.write(mimetype)
365
+ output.write("\n")
366
+ if output_format.output_format == "explain":
367
+ output.write(match.explain(ansi_color=output.isatty(), file=file_path))
368
+ if args.require_match and not found_match and not needs_sbud:
369
+ log.info("No matches found, exiting")
370
+ exit(127)
371
+ if omm:
372
+ log.clear_status()
373
+ elif not output_format.output_to_stdout:
374
+ log.info(f"Saved MIME output to {output_format.output_path}")
375
+ elif output_format.output_format == "json" or output_format.output_format == "sbud":
376
+ assert needs_sbud
377
+ json.dump(sbud, output)
378
+ if not output_format.output_to_stdout:
379
+ log.info(f"Saved {output_format.output_format.upper()} output to {output_format.output_path}")
380
+ elif output_format.output_format == "html":
381
+ assert needs_sbud
382
+ output.write(html.generate(file_path, sbud))
383
+ if not output_format.output_to_stdout:
384
+ log.info(f"Saved HTML output to {output_format.output_path}")
385
+ else:
386
+ # This should never happen because the output formats are constrained by argparse
387
+ raise NotImplementedError(f"TODO: Add support for output format {output_format!r}")
388
+
389
+ if sigterm_handler.terminated:
390
+ sys.exit(128 + signal.SIGTERM)
391
+
392
+
393
+ if __name__ == '__main__':
394
+ main()
polyfile/arithmetic.py ADDED
@@ -0,0 +1,27 @@
1
+ from typing import Callable, Dict, Tuple
2
+
3
+ import cint
4
+
5
+
6
+ CStyleInt = cint.Cint
7
+
8
+
9
+ INT_TYPES: Dict[Tuple[int, bool], Callable[[int], CStyleInt]] = {
10
+ (1, False): cint.U8,
11
+ (1, True): cint.I8,
12
+ (2, False): cint.U16,
13
+ (2, True): cint.I16,
14
+ (4, False): cint.U32,
15
+ (4, True): cint.I32,
16
+ (8, False): cint.U64,
17
+ (8, True): cint.I64
18
+ }
19
+
20
+
21
+ def make_c_style_int(value: int, num_bytes: int, signed: bool):
22
+ if (num_bytes, signed) not in INT_TYPES:
23
+ raise NotImplementedError(f"{num_bytes*8}-bit {['un',''][signed]}signed integers are not yet supported")
24
+ return INT_TYPES[(num_bytes, signed)](value)
25
+
26
+
27
+ setattr(CStyleInt, "new", make_c_style_int)
polyfile/ast.py ADDED
@@ -0,0 +1,114 @@
1
+ from typing import Any, Iterable, Iterator, List, Optional, Tuple, Union
2
+
3
+ from .polyfile import Match, Submatch
4
+
5
+
6
+ class Node:
7
+ def __init__(self,
8
+ name: str,
9
+ value: Optional[bytes] = None,
10
+ offset: Optional[int] = None,
11
+ length: Optional[int] = None,
12
+ older_sibling: Optional["Node"] = None,
13
+ children: Iterable["Node"] = ()
14
+ ):
15
+ self.name: str = name
16
+ self.value: Optional[bytes] = value
17
+ self._offset: Optional[int] = offset
18
+ self._length: Optional[int] = length
19
+ self.older_sibling: Optional[Node] = older_sibling
20
+ self.children: Tuple[Node, ...] = tuple(children)
21
+
22
+ def __repr__(self):
23
+ r = f"{self.__class__.__name__}(name={self.name!r}"
24
+ if self.value is not None:
25
+ r = f"{r}, value={self.value!r}"
26
+ r = f"{r}, offset={self.offset!r}, length={self.length!r}, older_sibling={self.older_sibling!r}, " \
27
+ f"children={self.children!r})"
28
+ return r
29
+
30
+ @property
31
+ def offset(self) -> int:
32
+ if self._offset is None:
33
+ if self.children:
34
+ self._offset = self.children[0].offset
35
+ elif self.older_sibling is not None:
36
+ self._offset = self.older_sibling.offset + self.older_sibling.length
37
+ else:
38
+ raise ValueError(f"{self!r} must either have an explicit offset, an older sibling, or a child!")
39
+ return self._offset
40
+
41
+ @property
42
+ def length(self) -> int:
43
+ if self._length is None:
44
+ if self.value is not None:
45
+ self._length = len(self.value)
46
+ elif not self.children:
47
+ self._length = 0
48
+ else:
49
+ self._length = self.children[-1].offset + self.children[-1].length - self.offset
50
+ return self._length
51
+
52
+ def to_matches(self, parent: Optional[Match] = None) -> Iterator[Submatch]:
53
+ stack: List[Tuple["Node", Optional[Match]]] = [(self, parent)]
54
+ while stack:
55
+ node, parent = stack.pop()
56
+ if parent is None:
57
+ parent_offset = 0
58
+ else:
59
+ parent_offset = parent.offset
60
+ match = Submatch(
61
+ name=node.name,
62
+ match_obj=node.value,
63
+ relative_offset=node.offset - parent_offset,
64
+ length=node.length,
65
+ parent=parent
66
+ )
67
+ yield match
68
+ for child in reversed(node.children):
69
+ stack.append((child, match))
70
+
71
+ @classmethod
72
+ def load(cls, obj: Any) -> "Node":
73
+ ancestors: List[Tuple[Any, Optional[Tuple[Node, ...]]]] = [
74
+ (obj, None)
75
+ ]
76
+ children: Optional[Tuple[Node, ...]]
77
+ while True:
78
+ obj, children = ancestors.pop()
79
+ if children is None:
80
+ if hasattr(obj, "children") and obj.children:
81
+ ancestors.append((obj, ()))
82
+ ancestors.extend((child, None) for child in reversed(obj.children))
83
+ continue
84
+ children = ()
85
+ if not hasattr(obj, "name"):
86
+ raise ValueError(f"{obj!r} does not have a `name` attribute!")
87
+ name: str = obj.name
88
+ if hasattr(obj, "value"):
89
+ value: Union[Optional[bytes], str] = obj.value
90
+ else:
91
+ value = None
92
+ if isinstance(value, str):
93
+ value = value.encode("utf-8")
94
+ if hasattr(obj, "offset"):
95
+ offset: Optional[int] = obj.offset
96
+ else:
97
+ offset = None
98
+ if hasattr(obj, "length") and (value is None or obj.length >= len(value)):
99
+ length: Optional[int] = obj.length
100
+ else:
101
+ length = None
102
+ older_sibling: Optional[Node] = None
103
+ for reversed_parent_index, (parent, siblings) in enumerate(reversed(ancestors)):
104
+ if siblings is not None:
105
+ if siblings:
106
+ older_sibling: Optional[Node] = siblings[-1]
107
+ break
108
+ else:
109
+ assert not ancestors
110
+ node = cls(name=name, value=value, offset=offset, length=length, older_sibling=older_sibling,
111
+ children=children)
112
+ if not ancestors:
113
+ return node
114
+ ancestors[len(ancestors) - reversed_parent_index - 1] = parent, siblings + (node,)