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/iterators.py ADDED
@@ -0,0 +1,72 @@
1
+ from collections.abc import Sequence as AbstractSequence, Set as AbstractSet
2
+ from typing import Generic, TypeVar, Iterable, Iterator, List, Optional, Sequence, Set
3
+
4
+ T = TypeVar("T")
5
+
6
+
7
+ class LazyIterableSequence(Generic[T], Sequence[T], AbstractSequence):
8
+ """A thread-safe list lazily generated from an iterator"""
9
+ def __init__(self, source: Iterable[T]):
10
+ self._source_iter: Optional[Iterator[T]] = iter(source)
11
+ self._items: List[T] = []
12
+
13
+ def _get_next_source_item(self) -> T:
14
+ if self._source_iter is None:
15
+ raise StopIteration()
16
+ return next(self._source_iter)
17
+
18
+ def _complete(self):
19
+ """Finishes reading all source items from the input iterator"""
20
+ while self._source_iter is not None:
21
+ try:
22
+ _ = self[len(self._items)]
23
+ except IndexError:
24
+ assert self._source_iter is None
25
+
26
+ def __getitem__(self, index: int) -> T:
27
+ while self._source_iter is not None and len(self._items) <= index:
28
+ # we have not yet read enough items
29
+ try:
30
+ self._items.append(next(self._source_iter))
31
+ except StopIteration:
32
+ self._source_iter = None
33
+ break
34
+ return self._items[index]
35
+
36
+ def __len__(self) -> int:
37
+ self._complete()
38
+ return len(self._items)
39
+
40
+ def __iter__(self) -> Iterator[T]:
41
+ i = 0
42
+ while True:
43
+ try:
44
+ yield self[i]
45
+ i += 1
46
+ except IndexError:
47
+ break
48
+
49
+
50
+ def unique(iterator: Iterator[T], elements: Optional[Set[T]] = None) -> Iterator[T]:
51
+ """Yields all of the unique elements of the input sequence"""
52
+ if elements is None:
53
+ elements = set()
54
+ for t in iterator:
55
+ if t not in elements:
56
+ yield t
57
+ elements.add(t)
58
+
59
+
60
+ class LazyIterableSet(Generic[T], AbstractSet, LazyIterableSequence[T]):
61
+ """
62
+ A collection that is both a set and a sequence that
63
+ """
64
+ def __init__(self, source: Iterable[T]):
65
+ self._set: Set[T] = set()
66
+ super().__init__(unique(iter(source), elements=self._set))
67
+
68
+ def __contains__(self, x: object) -> bool:
69
+ if x in self._set:
70
+ return True
71
+ self._complete()
72
+ return x in self._set
polyfile/jpeg.py ADDED
@@ -0,0 +1,24 @@
1
+ import base64
2
+ from io import BytesIO
3
+
4
+ from .fileutils import FileStream, Tempfile
5
+ from .polyfile import Match, register_parser, Submatch
6
+
7
+ from PIL import Image
8
+
9
+
10
+ @register_parser("image/jp2")
11
+ def parse_jpeg2000(file_stream: FileStream, parent: Match):
12
+ with Tempfile(file_stream.read(parent.length)) as input_bytes:
13
+ img = Image.open(input_bytes)
14
+ with BytesIO() as img_data:
15
+ img.save(img_data, "PNG")
16
+ b64data = f"data:image/png;base64,{base64.b64encode(img_data).decode('utf-8')}"
17
+ yield Submatch(
18
+ name='ImageData',
19
+ img_data=b64data,
20
+ match_obj="",
21
+ relative_offset=0,
22
+ length=parent.length,
23
+ parent=parent
24
+ )
File without changes
@@ -0,0 +1,156 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """
4
+ This module automates compilation of Kaitai Struct definitions into Python code.
5
+
6
+ This script is called from PolyFile's setup.py to compile the entire Kaitai Struct format library at build time.
7
+ Therefore, this script should always be self-contained and not require any dependencies other than the Python standard
8
+ library.
9
+
10
+ """
11
+ from io import BytesIO
12
+ import json
13
+ import os
14
+ from pathlib import Path
15
+ import shutil
16
+ import stat
17
+ import subprocess
18
+ import sys
19
+ from typing import Iterable, List, Optional, Union
20
+ from urllib.request import urlopen
21
+ from zipfile import ZipFile
22
+
23
+
24
+ if os.name == "nt":
25
+ KAITAI_COMPILER_NAME: str = "kaitai-struct-compiler.bat"
26
+ else:
27
+ KAITAI_COMPILER_NAME = "kaitai-struct-compiler"
28
+
29
+
30
+ COMPILER_DIR = Path(__file__).absolute().parent / "kaitai-struct-compiler-0.9"
31
+ COMPILER_BIN_DIR = COMPILER_DIR / "bin"
32
+ COMPILER_BIN = COMPILER_BIN_DIR / KAITAI_COMPILER_NAME
33
+
34
+
35
+ class KaitaiError(RuntimeError):
36
+ pass
37
+
38
+
39
+ class CompilationError(KaitaiError):
40
+ def __init__(self, ksy_file: str, message: str):
41
+ super().__init__(message)
42
+ self.ksy_file: str = ksy_file
43
+
44
+ def __str__(self):
45
+ return f"{self.ksy_file}: {super().__str__()}"
46
+
47
+
48
+ class CompiledKSY:
49
+ def __init__(self, class_name: str, python_path: Union[str, Path], dependencies: Iterable["CompiledKSY"] = ()):
50
+ self.class_name: str = class_name
51
+ if not isinstance(python_path, Path):
52
+ python_path = Path(python_path)
53
+ self.python_path: Path = python_path
54
+ self.dependencies: List[CompiledKSY] = list(dependencies)
55
+
56
+ def __repr__(self):
57
+ return f"{self.__class__.__name__}(class_name={self.class_name!r}, python_path={self.python_path!r}, "\
58
+ f"dependencies={self.dependencies!r})"
59
+
60
+
61
+ def install_compiler():
62
+ resp = urlopen("https://github.com/kaitai-io/kaitai_struct_compiler/releases/download/0.9/"
63
+ "kaitai-struct-compiler-0.9.zip")
64
+ zipfile = ZipFile(BytesIO(resp.read()))
65
+ COMPILER_DIR.mkdir(exist_ok=True)
66
+ zipfile.extractall(COMPILER_DIR.parent)
67
+ if COMPILER_BIN.exists():
68
+ COMPILER_BIN.chmod(COMPILER_BIN.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
69
+ sys.stderr.write(f"Installed the Kaitai Struct Compiler to {COMPILER_BIN}\n")
70
+
71
+
72
+ def compiler_path(auto_install: bool = True) -> Optional[Path]:
73
+ if COMPILER_BIN.exists():
74
+ return COMPILER_BIN
75
+ global_path = shutil.which(KAITAI_COMPILER_NAME)
76
+ if global_path is not None:
77
+ return Path(global_path)
78
+ if not auto_install:
79
+ return None
80
+ install_compiler()
81
+ return compiler_path(auto_install=False)
82
+
83
+
84
+ def compile(ksy_path: Union[str, Path], output_directory: Union[str, Path], auto_install: bool = True) -> CompiledKSY:
85
+ """Returns the list of compiled KSYs; the original spec being first, followed by its dependencies"""
86
+ compiler = compiler_path(auto_install=auto_install)
87
+ if compiler is None:
88
+ raise KaitaiError(f"{KAITAI_COMPILER_NAME} not found! Please make sure it is in your PATH. "
89
+ f"See https://kaitai.io/#download")
90
+
91
+ # sys.stderr.write(f"Using Kaitai Struct Compiler: {compiler!s}\n")
92
+
93
+ if not isinstance(output_directory, Path):
94
+ output_directory = Path(output_directory)
95
+
96
+ output_directory.mkdir(parents=True, exist_ok=True)
97
+
98
+ cmd = [
99
+ str(compiler), "--target", "python", "--outdir", str(output_directory), str(ksy_path),
100
+ "--debug", "--ksc-json-output", "-I", str(Path.cwd()), "--python-package", "polyfile.kaitai.parsers"
101
+ ]
102
+
103
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
104
+ out, err = proc.communicate()
105
+ if err:
106
+ raise KaitaiError(err.decode("utf-8"))
107
+ elif proc.returncode != 0:
108
+ raise KaitaiError(f"`{' '.join(cmd)}` returned with non-zero exit code {proc.returncode}")
109
+
110
+ result = json.loads(out)
111
+
112
+ if "errors" in result[ksy_path] and result[ksy_path]["errors"]:
113
+ raise KaitaiError(f"Error compiling {ksy_path}: {result[ksy_path]['errors'][0]['message']}")
114
+
115
+ first_spec_name = result[ksy_path]["firstSpecName"]
116
+ first_spec = result[ksy_path]["output"]["python"][first_spec_name]
117
+ if "errors" in first_spec:
118
+ for error in first_spec["errors"]:
119
+ raise CompilationError(ksy_file=error["file"], message=error["message"])
120
+ return CompiledKSY(
121
+ class_name=first_spec["topLevelName"],
122
+ python_path=output_directory / first_spec["files"][0]["fileName"],
123
+ dependencies=(
124
+ CompiledKSY(
125
+ class_name=compiled["topLevelName"],
126
+ python_path=output_directory / compiled["files"][0]["fileName"]
127
+ )
128
+ for spec_name, compiled in result[ksy_path]["output"]["python"].items()
129
+ if spec_name != first_spec_name
130
+ )
131
+ )
132
+
133
+
134
+ if __name__ == "__main__":
135
+ import argparse
136
+
137
+ if len(sys.argv) == 2 and sys.argv[1] == "--install":
138
+ if compiler_path() is None:
139
+ sys.exit(1)
140
+ else:
141
+ sys.exit(0)
142
+
143
+ parser = argparse.ArgumentParser(description="A Kaitai Struct to Python compiler")
144
+ parser.add_argument("KSY_PATH", type=str, help="path to the Kaitai Struct definition file")
145
+ parser.add_argument("OUTPUT_DIRECTORY", type=str, help="path to which to save the resulting Python")
146
+
147
+ args = parser.parse_args(sys.argv[1:])
148
+
149
+ try:
150
+ compiled = compile(args.KSY_PATH, args.OUTPUT_DIRECTORY)
151
+ print(f"{compiled.class_name}\t{compiled.python_path}")
152
+ for dep in compiled.dependencies:
153
+ print(f"{dep.class_name}\t{dep.python_path}")
154
+ except KaitaiError as e:
155
+ sys.stderr.write(f"{e!s}\n\n")
156
+ sys.exit(1)
@@ -0,0 +1,312 @@
1
+ from abc import ABC, abstractmethod
2
+ from dataclasses import dataclass
3
+ from enum import Enum
4
+ from importlib import resources
5
+ import importlib.util
6
+ import inspect
7
+ from io import BufferedReader, BytesIO
8
+ import json
9
+ from pathlib import Path
10
+ import sys
11
+ from typing import Any, Dict, Iterator, List, Optional, Set, Type, Union
12
+
13
+ from . import parsers
14
+ from .compiler import CompiledKSY
15
+ from ..fileutils import FileStream
16
+
17
+ from kaitaistruct import KaitaiStruct
18
+
19
+ with resources.path(parsers, "manifest.json") as manifest_path:
20
+ PARSER_DIR: Path = manifest_path.parent
21
+ if sys.version_info >= (3, 9):
22
+ with (resources.files(parsers) / "manifest.json").open("r") as f:
23
+ MANIFEST: Dict[str, Dict[str, Any]] = json.load(f)
24
+ else:
25
+ with resources.open_text(parsers, "manifest.json") as f:
26
+ MANIFEST = json.load(f)
27
+
28
+ COMPILED_INFO_BY_KSY: Dict[str, CompiledKSY] = {
29
+ ksy_path: CompiledKSY(
30
+ class_name=component["class_name"],
31
+ python_path=PARSER_DIR / component["python_path"],
32
+ dependencies=(
33
+ CompiledKSY(class_name=dep["class_name"], python_path=PARSER_DIR / dep["python_path"])
34
+ for dep in component["dependencies"]
35
+ )
36
+ )
37
+ for ksy_path, component in MANIFEST.items()
38
+ }
39
+ del MANIFEST
40
+
41
+ _IMPORTED_SPECS: Set[Path] = set()
42
+ _PARSERS_BY_KSY: Dict[str, Type[KaitaiStruct]] = {}
43
+
44
+
45
+ def import_spec(compiled: CompiledKSY) -> Optional[Type[KaitaiStruct]]:
46
+ if compiled.python_path in _IMPORTED_SPECS:
47
+ return None
48
+ _IMPORTED_SPECS.add(compiled.python_path)
49
+ module_name = compiled.python_path.name
50
+ assert module_name.lower().endswith(".py")
51
+ module_name = module_name[:-3]
52
+ module_name = f"{__name__}.parsers.{module_name}"
53
+ spec = importlib.util.spec_from_file_location(module_name, compiled.python_path)
54
+ module = importlib.util.module_from_spec(spec)
55
+ spec.loader.exec_module(module)
56
+ for objname, obj in inspect.getmembers(module):
57
+ if inspect.isclass(obj) and objname == compiled.class_name:
58
+ return obj
59
+ raise ImportError(f"Could not find parser class {compiled.class_name!r} in {compiled.python_path}")
60
+
61
+
62
+ @dataclass(unsafe_hash=True, order=True, frozen=True)
63
+ class Segment:
64
+ start: int
65
+ end: int
66
+
67
+ def __contains__(self, item):
68
+ return isinstance(item, Segment) and item.start >= self.start and item.end <= self.end
69
+
70
+ def __len__(self):
71
+ return self.end - self.start
72
+
73
+ def __bool__(self):
74
+ return len(self) > 0
75
+
76
+ def __getitem__(self, index_or_slice: Union[int, slice]):
77
+ if isinstance(index_or_slice, slice):
78
+ if index_or_slice.step is not None and index_or_slice.step != 1:
79
+ raise ValueError(f"{self.__class__.__name__}.__getitem__ only supports slices with step=1")
80
+ if index_or_slice.start is None:
81
+ new_start = self.start
82
+ else:
83
+ new_start = self.start + index_or_slice.start
84
+ if index_or_slice.stop is None:
85
+ new_end = self.end
86
+ elif index_or_slice.stop < 0:
87
+ new_end = self.end + index_or_slice.stop
88
+ else:
89
+ new_end = self.start + index_or_slice.stop
90
+ if new_start > self.end:
91
+ new_start = self.end
92
+ if new_end < new_start or new_end > self.end:
93
+ new_end = new_start
94
+ return Segment(new_start, new_end)
95
+ elif self.start + index_or_slice >= self.end or (index_or_slice < 0 and -index_or_slice > len(self)):
96
+ raise IndexError(index_or_slice)
97
+ elif index_or_slice < 0:
98
+ return Segment(self.end + index_or_slice, self.end + index_or_slice + 1)
99
+ else:
100
+ return Segment(self.start + index_or_slice, self.start + index_or_slice + 1)
101
+
102
+
103
+ class ASTNode:
104
+ """Represents an element in a parse."""
105
+
106
+ def __init__(
107
+ self,
108
+ name: str,
109
+ segment: Segment,
110
+ offset: int,
111
+ parent: Optional["CompoundNode"] = None
112
+ ):
113
+ self.name: str = name
114
+ self.segment: Segment = segment
115
+ self.offset: int = offset
116
+ if parent is None:
117
+ if not isinstance(self, RootNode):
118
+ raise ValueError(f"Only a RootNode can have no parent, not {self!r}")
119
+ self.root: RootNode = self
120
+ self.level: int = 0
121
+ else:
122
+ self.root = parent.root
123
+ self.level = parent.level + 1
124
+ self.parent: Optional[CompoundNode] = parent
125
+
126
+ def dfs(self) -> Iterator["ASTNode"]:
127
+ yield self
128
+
129
+ @property
130
+ def start(self) -> int:
131
+ return self.offset + self.segment.start
132
+
133
+ @property
134
+ def end(self) -> int:
135
+ return self.offset + self.segment.end
136
+
137
+ @property
138
+ def raw_value(self):
139
+ """Sequence of bytes of this segment."""
140
+ return self.root.get_value(self.start, self.end)
141
+
142
+ @property
143
+ def size(self) -> int:
144
+ return self.end - self.start
145
+
146
+ @property
147
+ def children(self) -> List["ASTNode"]:
148
+ return []
149
+
150
+ def __repr__(self):
151
+ return f"{self.name}({self.__class__.__name__}) [{self.start}:{self.end}]"
152
+
153
+
154
+ class ValueNode(ASTNode):
155
+ """A leaf in the parse tree."""
156
+
157
+ TYPES = (int, float, str, bytes, Enum)
158
+
159
+ def __init__(self, value: bytes, *args, **kwargs):
160
+ self._value: bytes = value
161
+ super().__init__(*args, **kwargs)
162
+
163
+ @property
164
+ def value(self) -> bytes:
165
+ return self._value
166
+
167
+ def __repr__(self):
168
+ return f"{self.name}({self.__class__.__name__}<{self.value.__class__.__name__}>) [{self.start}:{self.end}]"
169
+
170
+
171
+ class CompoundNode(ASTNode, ABC):
172
+ """A node that can have children"""
173
+
174
+ def __init__(self, obj: KaitaiStruct, *args, **kwargs):
175
+ self.obj: KaitaiStruct = obj
176
+ super().__init__(*args, **kwargs)
177
+ self._children: Optional[List[ASTNode]] = None
178
+
179
+ @property
180
+ def children(self) -> List[ASTNode]:
181
+ if self._children is None:
182
+ self._children = list(self.explore())
183
+ return self._children
184
+
185
+ @abstractmethod
186
+ def explore(self) -> Iterator[ASTNode]:
187
+ raise NotImplementedError()
188
+
189
+ def dfs(self) -> Iterator[ASTNode]:
190
+ stack = [self]
191
+ while stack:
192
+ top = stack.pop()
193
+ yield top
194
+ stack.extend(reversed(top.children))
195
+
196
+ def make_child(
197
+ self,
198
+ obj: KaitaiStruct,
199
+ name: str,
200
+ segment: Segment,
201
+ offset: int,
202
+ ) -> ASTNode:
203
+ if isinstance(obj, KaitaiStruct):
204
+ node_class = StructNode
205
+ elif isinstance(obj, ValueNode.TYPES):
206
+ node_class = ValueNode
207
+ elif isinstance(obj, list):
208
+ node_class = ArrayNode
209
+ else:
210
+ raise TypeError(f"Unknown object type: {type(obj)}")
211
+
212
+ return node_class(obj, name, segment, offset, self)
213
+
214
+
215
+ class StructNode(CompoundNode):
216
+ """Represents node of the subtype."""
217
+
218
+ def explore(self) -> Iterator[ASTNode]:
219
+ for name in self.obj.SEQ_FIELDS:
220
+ markers = self.obj._debug[name].copy()
221
+ if "arr" in markers:
222
+ del markers["arr"]
223
+ if "start" not in markers or "end" not in markers:
224
+ continue
225
+ segment = Segment(**markers)
226
+ offset = self.offset
227
+ if isinstance(self.parent, StructNode):
228
+ if self.obj._io != self.parent.obj._io:
229
+ offset = self.start
230
+ if hasattr(self.obj, name):
231
+ yield self.make_child(getattr(self.obj, name), name, segment, offset)
232
+
233
+
234
+ class ArrayNode(CompoundNode):
235
+ """Represents node of array of subtype items."""
236
+
237
+ def explore(self) -> Iterator[ASTNode]:
238
+ for i, obj in enumerate(self.obj):
239
+ markers = self.parent.obj._debug[self.name]["arr"][i]
240
+ segment = Segment(**markers)
241
+ name = f"{self.name}[{i}]"
242
+ yield self.make_child(obj, name, segment, self.offset)
243
+
244
+
245
+ class RootNode(StructNode):
246
+ def __init__(self, buffer: bytes, obj: KaitaiStruct):
247
+ self.buffer: bytes = buffer
248
+ super().__init__(obj, name=obj.__class__.__name__, segment=Segment(0, len(self.buffer)), offset=0)
249
+
250
+ def get_value(self, start, end):
251
+ return self.buffer[start:end]
252
+
253
+
254
+ class KaitaiInspector:
255
+ def __init__(self, struct: KaitaiStruct):
256
+ self.struct: KaitaiStruct = struct
257
+ self._ast: Optional[RootNode] = None
258
+
259
+ @property
260
+ def ast(self) -> RootNode:
261
+ if self._ast is None:
262
+ _io = self.struct._io._io
263
+ if isinstance(_io, FileStream):
264
+ buffer = _io.content
265
+ elif isinstance(_io, BytesIO):
266
+ buffer = _io.getbuffer().tobytes()
267
+ elif isinstance(_io, BufferedReader):
268
+ with open(self.struct._io._io.name, 'rb') as f:
269
+ buffer = f.read()
270
+ else:
271
+ raise TypeError('Unsupported stream type')
272
+
273
+ self._ast = RootNode(buffer, self.struct)
274
+
275
+ return self._ast
276
+
277
+
278
+ class KaitaiParser:
279
+ def __init__(self, struct_type: Type[KaitaiStruct]):
280
+ self.struct_type: Type[KaitaiStruct] = struct_type
281
+
282
+ @staticmethod
283
+ def load(ksy_path: str) -> "KaitaiParser":
284
+ """Returns a parser for the given KSY file and input file.
285
+
286
+ The KSY file is specified as a relative path to the file within the Kaitai struct format library.
287
+ Examples:
288
+
289
+ "executable/dos_mz.ksy"
290
+ "image/jpeg.ksy"
291
+ "network/pcap.ksy"
292
+
293
+ """
294
+ if ksy_path not in _PARSERS_BY_KSY:
295
+ if ksy_path not in COMPILED_INFO_BY_KSY:
296
+ raise KeyError(ksy_path)
297
+ info = COMPILED_INFO_BY_KSY[ksy_path]
298
+ _PARSERS_BY_KSY[ksy_path] = import_spec(info) # type: ignore
299
+ return KaitaiParser(_PARSERS_BY_KSY[ksy_path])
300
+
301
+ def parse(self, input_file_path_or_content: Union[str, Path, bytes, BytesIO]) -> KaitaiInspector:
302
+ if isinstance(input_file_path_or_content, Path):
303
+ input_file_path_or_content = str(input_file_path_or_content)
304
+ if isinstance(input_file_path_or_content, str):
305
+ struct = self.struct_type.from_file(input_file_path_or_content)
306
+ elif isinstance(input_file_path_or_content, bytes):
307
+ struct = self.struct_type.from_bytes(input_file_path_or_content)
308
+ else:
309
+ # Treat it like BytesIO
310
+ struct = self.struct_type.from_io(input_file_path_or_content)
311
+ struct._read()
312
+ return KaitaiInspector(struct)
File without changes
@@ -0,0 +1,116 @@
1
+ # This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
2
+
3
+ from pkg_resources import parse_version
4
+ import kaitaistruct
5
+ from kaitaistruct import KaitaiStruct, KaitaiStream, BytesIO
6
+ from enum import Enum
7
+ import collections
8
+
9
+
10
+ if parse_version(kaitaistruct.__version__) < parse_version('0.9'):
11
+ raise Exception("Incompatible Kaitai Struct Python API: 0.9 or later is required, but you have %s" % (kaitaistruct.__version__))
12
+
13
+ class AixUtmp(KaitaiStruct):
14
+ """This spec can be used to parse utmp, wtmp and other similar as created by IBM AIX.
15
+
16
+ .. seealso::
17
+ Source - https://www.ibm.com/docs/en/aix/7.1?topic=files-utmph-file
18
+ """
19
+
20
+ class EntryType(Enum):
21
+ empty = 0
22
+ run_lvl = 1
23
+ boot_time = 2
24
+ old_time = 3
25
+ new_time = 4
26
+ init_process = 5
27
+ login_process = 6
28
+ user_process = 7
29
+ dead_process = 8
30
+ accounting = 9
31
+ SEQ_FIELDS = ["records"]
32
+ def __init__(self, _io, _parent=None, _root=None):
33
+ self._io = _io
34
+ self._parent = _parent
35
+ self._root = _root if _root else self
36
+ self._debug = collections.defaultdict(dict)
37
+
38
+ def _read(self):
39
+ self._debug['records']['start'] = self._io.pos()
40
+ self.records = []
41
+ i = 0
42
+ while not self._io.is_eof():
43
+ if not 'arr' in self._debug['records']:
44
+ self._debug['records']['arr'] = []
45
+ self._debug['records']['arr'].append({'start': self._io.pos()})
46
+ _t_records = AixUtmp.Record(self._io, self, self._root)
47
+ _t_records._read()
48
+ self.records.append(_t_records)
49
+ self._debug['records']['arr'][len(self.records) - 1]['end'] = self._io.pos()
50
+ i += 1
51
+
52
+ self._debug['records']['end'] = self._io.pos()
53
+
54
+ class Record(KaitaiStruct):
55
+ SEQ_FIELDS = ["user", "inittab_id", "device", "pid", "type", "timestamp", "exit_status", "hostname", "dbl_word_pad", "reserved_a", "reserved_v"]
56
+ def __init__(self, _io, _parent=None, _root=None):
57
+ self._io = _io
58
+ self._parent = _parent
59
+ self._root = _root if _root else self
60
+ self._debug = collections.defaultdict(dict)
61
+
62
+ def _read(self):
63
+ self._debug['user']['start'] = self._io.pos()
64
+ self.user = (self._io.read_bytes(256)).decode(u"ascii")
65
+ self._debug['user']['end'] = self._io.pos()
66
+ self._debug['inittab_id']['start'] = self._io.pos()
67
+ self.inittab_id = (self._io.read_bytes(14)).decode(u"ascii")
68
+ self._debug['inittab_id']['end'] = self._io.pos()
69
+ self._debug['device']['start'] = self._io.pos()
70
+ self.device = (self._io.read_bytes(64)).decode(u"ascii")
71
+ self._debug['device']['end'] = self._io.pos()
72
+ self._debug['pid']['start'] = self._io.pos()
73
+ self.pid = self._io.read_u8be()
74
+ self._debug['pid']['end'] = self._io.pos()
75
+ self._debug['type']['start'] = self._io.pos()
76
+ self.type = KaitaiStream.resolve_enum(AixUtmp.EntryType, self._io.read_s2be())
77
+ self._debug['type']['end'] = self._io.pos()
78
+ self._debug['timestamp']['start'] = self._io.pos()
79
+ self.timestamp = self._io.read_s8be()
80
+ self._debug['timestamp']['end'] = self._io.pos()
81
+ self._debug['exit_status']['start'] = self._io.pos()
82
+ self.exit_status = AixUtmp.ExitStatus(self._io, self, self._root)
83
+ self.exit_status._read()
84
+ self._debug['exit_status']['end'] = self._io.pos()
85
+ self._debug['hostname']['start'] = self._io.pos()
86
+ self.hostname = (self._io.read_bytes(256)).decode(u"ascii")
87
+ self._debug['hostname']['end'] = self._io.pos()
88
+ self._debug['dbl_word_pad']['start'] = self._io.pos()
89
+ self.dbl_word_pad = self._io.read_s4be()
90
+ self._debug['dbl_word_pad']['end'] = self._io.pos()
91
+ self._debug['reserved_a']['start'] = self._io.pos()
92
+ self.reserved_a = self._io.read_bytes(8)
93
+ self._debug['reserved_a']['end'] = self._io.pos()
94
+ self._debug['reserved_v']['start'] = self._io.pos()
95
+ self.reserved_v = self._io.read_bytes(24)
96
+ self._debug['reserved_v']['end'] = self._io.pos()
97
+
98
+
99
+ class ExitStatus(KaitaiStruct):
100
+ SEQ_FIELDS = ["termination_code", "exit_code"]
101
+ def __init__(self, _io, _parent=None, _root=None):
102
+ self._io = _io
103
+ self._parent = _parent
104
+ self._root = _root if _root else self
105
+ self._debug = collections.defaultdict(dict)
106
+
107
+ def _read(self):
108
+ self._debug['termination_code']['start'] = self._io.pos()
109
+ self.termination_code = self._io.read_s2be()
110
+ self._debug['termination_code']['end'] = self._io.pos()
111
+ self._debug['exit_code']['start'] = self._io.pos()
112
+ self.exit_code = self._io.read_s2be()
113
+ self._debug['exit_code']['end'] = self._io.pos()
114
+
115
+
116
+