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.
- polyfile/__init__.py +15 -0
- polyfile/__main__.py +394 -0
- polyfile/arithmetic.py +27 -0
- polyfile/ast.py +114 -0
- polyfile/debugger.py +1039 -0
- polyfile/expressions.py +346 -0
- polyfile/fileutils.py +343 -0
- polyfile/html.py +135 -0
- polyfile/http/__init__.py +1 -0
- polyfile/http/defacto.py +37 -0
- polyfile/http/deprecated.py +51 -0
- polyfile/http/experimental.py +67 -0
- polyfile/http/http_11.py +548 -0
- polyfile/http/matcher.py +37 -0
- polyfile/http/structured_headers.py +48 -0
- polyfile/iterators.py +72 -0
- polyfile/jpeg.py +24 -0
- polyfile/kaitai/__init__.py +0 -0
- polyfile/kaitai/compiler.py +156 -0
- polyfile/kaitai/parser.py +312 -0
- polyfile/kaitai/parsers/__init__.py +0 -0
- polyfile/kaitai/parsers/aix_utmp.py +116 -0
- polyfile/kaitai/parsers/allegro_dat.py +367 -0
- polyfile/kaitai/parsers/andes_firmware.py +64 -0
- polyfile/kaitai/parsers/android_bootldr_asus.py +105 -0
- polyfile/kaitai/parsers/android_bootldr_huawei.py +181 -0
- polyfile/kaitai/parsers/android_bootldr_qcom.py +217 -0
- polyfile/kaitai/parsers/android_dto.py +138 -0
- polyfile/kaitai/parsers/android_img.py +319 -0
- polyfile/kaitai/parsers/android_nanoapp_header.py +83 -0
- polyfile/kaitai/parsers/android_opengl_shaders_cache.py +151 -0
- polyfile/kaitai/parsers/android_sparse.py +237 -0
- polyfile/kaitai/parsers/android_super.py +401 -0
- polyfile/kaitai/parsers/apm_partition_table.py +196 -0
- polyfile/kaitai/parsers/apple_single_double.py +180 -0
- polyfile/kaitai/parsers/asn1_der.py +235 -0
- polyfile/kaitai/parsers/au.py +138 -0
- polyfile/kaitai/parsers/avantes_roh60.py +112 -0
- polyfile/kaitai/parsers/avi.py +296 -0
- polyfile/kaitai/parsers/bcd.py +111 -0
- polyfile/kaitai/parsers/bitcoin_transaction.py +210 -0
- polyfile/kaitai/parsers/blender_blend.py +334 -0
- polyfile/kaitai/parsers/bmp.py +780 -0
- polyfile/kaitai/parsers/bson.py +411 -0
- polyfile/kaitai/parsers/btrfs_stream.py +318 -0
- polyfile/kaitai/parsers/bytes_with_io.py +27 -0
- polyfile/kaitai/parsers/chrome_pak.py +194 -0
- polyfile/kaitai/parsers/code_6502.py +456 -0
- polyfile/kaitai/parsers/compressed_resource.py +217 -0
- polyfile/kaitai/parsers/cpio_old_le.py +154 -0
- polyfile/kaitai/parsers/cramfs.py +344 -0
- polyfile/kaitai/parsers/creative_voice_file.py +342 -0
- polyfile/kaitai/parsers/dbf.py +274 -0
- polyfile/kaitai/parsers/dcmp_0.py +664 -0
- polyfile/kaitai/parsers/dcmp_1.py +422 -0
- polyfile/kaitai/parsers/dcmp_2.py +312 -0
- polyfile/kaitai/parsers/dcmp_variable_length_integer.py +66 -0
- polyfile/kaitai/parsers/dex.py +1086 -0
- polyfile/kaitai/parsers/dicom.py +4370 -0
- polyfile/kaitai/parsers/dime_message.py +201 -0
- polyfile/kaitai/parsers/dns_packet.py +569 -0
- polyfile/kaitai/parsers/doom_wad.py +654 -0
- polyfile/kaitai/parsers/dos_datetime.py +191 -0
- polyfile/kaitai/parsers/dos_mz.py +172 -0
- polyfile/kaitai/parsers/ds_store.py +513 -0
- polyfile/kaitai/parsers/dtb.py +310 -0
- polyfile/kaitai/parsers/dune_2_pak.py +126 -0
- polyfile/kaitai/parsers/edid.py +472 -0
- polyfile/kaitai/parsers/efivar_signature_list.py +331 -0
- polyfile/kaitai/parsers/elf.py +2482 -0
- polyfile/kaitai/parsers/ethernet_frame.py +114 -0
- polyfile/kaitai/parsers/exif.py +723 -0
- polyfile/kaitai/parsers/ext2.py +537 -0
- polyfile/kaitai/parsers/fallout2_dat.py +187 -0
- polyfile/kaitai/parsers/fallout_dat.py +156 -0
- polyfile/kaitai/parsers/fasttracker_xm_module.py +558 -0
- polyfile/kaitai/parsers/ftl_dat.py +90 -0
- polyfile/kaitai/parsers/genmidi_op2.py +161 -0
- polyfile/kaitai/parsers/gettext_mo.py +541 -0
- polyfile/kaitai/parsers/gif.py +492 -0
- polyfile/kaitai/parsers/gimp_brush.py +244 -0
- polyfile/kaitai/parsers/glibc_utmp.py +114 -0
- polyfile/kaitai/parsers/gltf_binary.py +132 -0
- polyfile/kaitai/parsers/google_protobuf.py +151 -0
- polyfile/kaitai/parsers/gpt_partition_table.py +175 -0
- polyfile/kaitai/parsers/gran_turismo_vol.py +140 -0
- polyfile/kaitai/parsers/grub2_font.py +337 -0
- polyfile/kaitai/parsers/gzip.py +232 -0
- polyfile/kaitai/parsers/hashcat_restore.py +60 -0
- polyfile/kaitai/parsers/hccap.py +111 -0
- polyfile/kaitai/parsers/hccapx.py +103 -0
- polyfile/kaitai/parsers/heaps_pak.py +177 -0
- polyfile/kaitai/parsers/heroes_of_might_and_magic_agg.py +116 -0
- polyfile/kaitai/parsers/heroes_of_might_and_magic_bmp.py +34 -0
- polyfile/kaitai/parsers/icmp_packet.py +136 -0
- polyfile/kaitai/parsers/ico.py +129 -0
- polyfile/kaitai/parsers/id3v1_1.py +220 -0
- polyfile/kaitai/parsers/id3v2_3.py +324 -0
- polyfile/kaitai/parsers/id3v2_4.py +423 -0
- polyfile/kaitai/parsers/ines.py +282 -0
- polyfile/kaitai/parsers/ipv4_packet.py +158 -0
- polyfile/kaitai/parsers/ipv6_packet.py +55 -0
- polyfile/kaitai/parsers/iso9660.py +544 -0
- polyfile/kaitai/parsers/java_class.py +1113 -0
- polyfile/kaitai/parsers/jpeg.py +361 -0
- polyfile/kaitai/parsers/luks.py +149 -0
- polyfile/kaitai/parsers/lzh.py +165 -0
- polyfile/kaitai/parsers/mac_os_resource_snd.py +493 -0
- polyfile/kaitai/parsers/mach_o.py +3033 -0
- polyfile/kaitai/parsers/mach_o_fat.py +92 -0
- polyfile/kaitai/parsers/magicavoxel_vox.py +391 -0
- polyfile/kaitai/parsers/manifest.json +1 -0
- polyfile/kaitai/parsers/mbr_partition_table.py +119 -0
- polyfile/kaitai/parsers/mcap.py +1015 -0
- polyfile/kaitai/parsers/microsoft_cfb.py +293 -0
- polyfile/kaitai/parsers/microsoft_network_monitor_v2.py +309 -0
- polyfile/kaitai/parsers/microsoft_pe.py +765 -0
- polyfile/kaitai/parsers/mifare_classic.py +706 -0
- polyfile/kaitai/parsers/minecraft_nbt.py +449 -0
- polyfile/kaitai/parsers/monomakh_sapr_chg.py +69 -0
- polyfile/kaitai/parsers/mozilla_mar.py +239 -0
- polyfile/kaitai/parsers/mp4.py +333 -0
- polyfile/kaitai/parsers/msgpack.py +467 -0
- polyfile/kaitai/parsers/nitf.py +1189 -0
- polyfile/kaitai/parsers/nt_mdt_pal.py +155 -0
- polyfile/kaitai/parsers/ogg.py +118 -0
- polyfile/kaitai/parsers/openpgp_message.py +993 -0
- polyfile/kaitai/parsers/packet_ppi.py +515 -0
- polyfile/kaitai/parsers/pcap.py +344 -0
- polyfile/kaitai/parsers/pcf_font.py +506 -0
- polyfile/kaitai/parsers/pcx.py +195 -0
- polyfile/kaitai/parsers/pcx_dcx.py +79 -0
- polyfile/kaitai/parsers/phar_without_stub.py +399 -0
- polyfile/kaitai/parsers/php_serialized_value.py +505 -0
- polyfile/kaitai/parsers/png.py +721 -0
- polyfile/kaitai/parsers/protocol_body.py +260 -0
- polyfile/kaitai/parsers/psx_tim.py +104 -0
- polyfile/kaitai/parsers/python_pickle.py +718 -0
- polyfile/kaitai/parsers/python_pyc_27.py +510 -0
- polyfile/kaitai/parsers/quake_mdl.py +441 -0
- polyfile/kaitai/parsers/quake_pak.py +112 -0
- polyfile/kaitai/parsers/quicktime_mov.py +634 -0
- polyfile/kaitai/parsers/rar.py +265 -0
- polyfile/kaitai/parsers/regf.py +569 -0
- polyfile/kaitai/parsers/renderware_binary_stream.py +877 -0
- polyfile/kaitai/parsers/resource_fork.py +611 -0
- polyfile/kaitai/parsers/respack.py +57 -0
- polyfile/kaitai/parsers/riff.py +409 -0
- polyfile/kaitai/parsers/rpm.py +964 -0
- polyfile/kaitai/parsers/rtcp_payload.py +579 -0
- polyfile/kaitai/parsers/rtp_packet.py +150 -0
- polyfile/kaitai/parsers/rtpdump.py +115 -0
- polyfile/kaitai/parsers/ruby_marshal.py +423 -0
- polyfile/kaitai/parsers/s3m.py +493 -0
- polyfile/kaitai/parsers/saints_row_2_vpp_pc.py +254 -0
- polyfile/kaitai/parsers/shapefile_index.py +174 -0
- polyfile/kaitai/parsers/shapefile_main.py +893 -0
- polyfile/kaitai/parsers/some_ip.py +209 -0
- polyfile/kaitai/parsers/some_ip_container.py +37 -0
- polyfile/kaitai/parsers/some_ip_sd.py +86 -0
- polyfile/kaitai/parsers/some_ip_sd_entries.py +160 -0
- polyfile/kaitai/parsers/some_ip_sd_options.py +374 -0
- polyfile/kaitai/parsers/specpr.py +404 -0
- polyfile/kaitai/parsers/sqlite3.py +472 -0
- polyfile/kaitai/parsers/ssh_public_key.py +252 -0
- polyfile/kaitai/parsers/standard_midi_file.py +390 -0
- polyfile/kaitai/parsers/stl.py +111 -0
- polyfile/kaitai/parsers/sudoers_ts.py +201 -0
- polyfile/kaitai/parsers/swf.py +406 -0
- polyfile/kaitai/parsers/systemd_journal.py +361 -0
- polyfile/kaitai/parsers/tcp_segment.py +57 -0
- polyfile/kaitai/parsers/tga.py +213 -0
- polyfile/kaitai/parsers/tls_client_hello.py +293 -0
- polyfile/kaitai/parsers/tr_dos_image.py +322 -0
- polyfile/kaitai/parsers/tsm.py +198 -0
- polyfile/kaitai/parsers/ttf.py +1847 -0
- polyfile/kaitai/parsers/udp_datagram.py +42 -0
- polyfile/kaitai/parsers/uefi_te.py +236 -0
- polyfile/kaitai/parsers/uimage.py +198 -0
- polyfile/kaitai/parsers/utf8_string.py +137 -0
- polyfile/kaitai/parsers/vfat.py +410 -0
- polyfile/kaitai/parsers/vlq_base128_be.py +104 -0
- polyfile/kaitai/parsers/vlq_base128_le.py +129 -0
- polyfile/kaitai/parsers/vmware_vmdk.py +167 -0
- polyfile/kaitai/parsers/vp8_ivf.py +112 -0
- polyfile/kaitai/parsers/warcraft_2_pud.py +423 -0
- polyfile/kaitai/parsers/wav.py +1014 -0
- polyfile/kaitai/parsers/websocket.py +167 -0
- polyfile/kaitai/parsers/windows_evt_log.py +304 -0
- polyfile/kaitai/parsers/windows_lnk_file.py +467 -0
- polyfile/kaitai/parsers/windows_minidump.py +575 -0
- polyfile/kaitai/parsers/windows_resource_file.py +243 -0
- polyfile/kaitai/parsers/windows_shell_items.py +190 -0
- polyfile/kaitai/parsers/windows_systemtime.py +52 -0
- polyfile/kaitai/parsers/wmf.py +502 -0
- polyfile/kaitai/parsers/xar.py +181 -0
- polyfile/kaitai/parsers/xwd.py +189 -0
- polyfile/kaitai/parsers/zip.py +685 -0
- polyfile/kaitai/parsers/zisofs.py +158 -0
- polyfile/kaitai/parsers/zx_spectrum_tap.py +184 -0
- polyfile/kaitaimatcher.py +113 -0
- polyfile/languagematcher.py +217 -0
- polyfile/logger.py +135 -0
- polyfile/magic.py +2983 -0
- polyfile/magic_defs/COPYING +29 -0
- polyfile/magic_defs/__init__.py +0 -0
- polyfile/magic_defs/acorn +102 -0
- polyfile/magic_defs/adi +13 -0
- polyfile/magic_defs/adventure +122 -0
- polyfile/magic_defs/aes +29 -0
- polyfile/magic_defs/algol68 +35 -0
- polyfile/magic_defs/allegro +9 -0
- polyfile/magic_defs/alliant +18 -0
- polyfile/magic_defs/alpha +32 -0
- polyfile/magic_defs/amanda +12 -0
- polyfile/magic_defs/amigaos +218 -0
- polyfile/magic_defs/android +259 -0
- polyfile/magic_defs/animation +1197 -0
- polyfile/magic_defs/aout +46 -0
- polyfile/magic_defs/apache +28 -0
- polyfile/magic_defs/apl +7 -0
- polyfile/magic_defs/apple +773 -0
- polyfile/magic_defs/application +7 -0
- polyfile/magic_defs/applix +13 -0
- polyfile/magic_defs/apt +52 -0
- polyfile/magic_defs/archive +2586 -0
- polyfile/magic_defs/aria +38 -0
- polyfile/magic_defs/arm +50 -0
- polyfile/magic_defs/asf +132 -0
- polyfile/magic_defs/assembler +18 -0
- polyfile/magic_defs/asterix +18 -0
- polyfile/magic_defs/att3b +41 -0
- polyfile/magic_defs/audio +1291 -0
- polyfile/magic_defs/avm +33 -0
- polyfile/magic_defs/basis +18 -0
- polyfile/magic_defs/beetle +7 -0
- polyfile/magic_defs/ber +65 -0
- polyfile/magic_defs/bflt +14 -0
- polyfile/magic_defs/bhl +10 -0
- polyfile/magic_defs/bioinformatics +178 -0
- polyfile/magic_defs/biosig +154 -0
- polyfile/magic_defs/blackberry +8 -0
- polyfile/magic_defs/blcr +25 -0
- polyfile/magic_defs/blender +50 -0
- polyfile/magic_defs/blit +24 -0
- polyfile/magic_defs/bm +10 -0
- polyfile/magic_defs/bout +11 -0
- polyfile/magic_defs/bsdi +33 -0
- polyfile/magic_defs/bsi +10 -0
- polyfile/magic_defs/btsnoop +13 -0
- polyfile/magic_defs/burp +7 -0
- polyfile/magic_defs/bytecode +41 -0
- polyfile/magic_defs/c-lang +110 -0
- polyfile/magic_defs/c64 +531 -0
- polyfile/magic_defs/cad +437 -0
- polyfile/magic_defs/cafebabe +107 -0
- polyfile/magic_defs/cbor +21 -0
- polyfile/magic_defs/ccf +14 -0
- polyfile/magic_defs/cddb +12 -0
- polyfile/magic_defs/chord +15 -0
- polyfile/magic_defs/cisco +12 -0
- polyfile/magic_defs/citrus +12 -0
- polyfile/magic_defs/clarion +27 -0
- polyfile/magic_defs/claris +48 -0
- polyfile/magic_defs/clipper +65 -0
- polyfile/magic_defs/clojure +30 -0
- polyfile/magic_defs/coff +98 -0
- polyfile/magic_defs/commands +201 -0
- polyfile/magic_defs/communications +22 -0
- polyfile/magic_defs/compress +461 -0
- polyfile/magic_defs/console +1213 -0
- polyfile/magic_defs/convex +69 -0
- polyfile/magic_defs/coverage +91 -0
- polyfile/magic_defs/cracklib +14 -0
- polyfile/magic_defs/crypto +31 -0
- polyfile/magic_defs/csv +8 -0
- polyfile/magic_defs/ctags +6 -0
- polyfile/magic_defs/ctf +23 -0
- polyfile/magic_defs/cubemap +8 -0
- polyfile/magic_defs/cups +56 -0
- polyfile/magic_defs/dact +11 -0
- polyfile/magic_defs/database +886 -0
- polyfile/magic_defs/dataone +47 -0
- polyfile/magic_defs/dbpf +15 -0
- polyfile/magic_defs/der +146 -0
- polyfile/magic_defs/diamond +12 -0
- polyfile/magic_defs/dif +33 -0
- polyfile/magic_defs/diff +41 -0
- polyfile/magic_defs/digital +59 -0
- polyfile/magic_defs/dolby +69 -0
- polyfile/magic_defs/dsf +25 -0
- polyfile/magic_defs/dump +96 -0
- polyfile/magic_defs/dwarfs +45 -0
- polyfile/magic_defs/dyadic +61 -0
- polyfile/magic_defs/ebml +8 -0
- polyfile/magic_defs/edid +11 -0
- polyfile/magic_defs/editors +43 -0
- polyfile/magic_defs/efi +15 -0
- polyfile/magic_defs/elf +379 -0
- polyfile/magic_defs/encore +22 -0
- polyfile/magic_defs/epoc +62 -0
- polyfile/magic_defs/erlang +21 -0
- polyfile/magic_defs/espressif +57 -0
- polyfile/magic_defs/esri +28 -0
- polyfile/magic_defs/etf +33 -0
- polyfile/magic_defs/fcs +9 -0
- polyfile/magic_defs/filesystems +2694 -0
- polyfile/magic_defs/finger +16 -0
- polyfile/magic_defs/firmware +133 -0
- polyfile/magic_defs/flash +62 -0
- polyfile/magic_defs/flif +36 -0
- polyfile/magic_defs/fonts +449 -0
- polyfile/magic_defs/forth +82 -0
- polyfile/magic_defs/fortran +9 -0
- polyfile/magic_defs/frame +62 -0
- polyfile/magic_defs/freebsd +164 -0
- polyfile/magic_defs/fsav +128 -0
- polyfile/magic_defs/fusecompress +12 -0
- polyfile/magic_defs/games +696 -0
- polyfile/magic_defs/gcc +17 -0
- polyfile/magic_defs/gconv +10 -0
- polyfile/magic_defs/gentoo +85 -0
- polyfile/magic_defs/geo +166 -0
- polyfile/magic_defs/geos +20 -0
- polyfile/magic_defs/gimp +77 -0
- polyfile/magic_defs/git +13 -0
- polyfile/magic_defs/glibc +21 -0
- polyfile/magic_defs/gnome +59 -0
- polyfile/magic_defs/gnu +173 -0
- polyfile/magic_defs/gnumeric +8 -0
- polyfile/magic_defs/gpt +240 -0
- polyfile/magic_defs/gpu +28 -0
- polyfile/magic_defs/grace +21 -0
- polyfile/magic_defs/graphviz +12 -0
- polyfile/magic_defs/gringotts +48 -0
- polyfile/magic_defs/guile +13 -0
- polyfile/magic_defs/hardware +12 -0
- polyfile/magic_defs/hitachi-sh +30 -0
- polyfile/magic_defs/hp +433 -0
- polyfile/magic_defs/human68k +26 -0
- polyfile/magic_defs/ibm370 +52 -0
- polyfile/magic_defs/ibm6000 +35 -0
- polyfile/magic_defs/icc +214 -0
- polyfile/magic_defs/iff +80 -0
- polyfile/magic_defs/images +4210 -0
- polyfile/magic_defs/inform +9 -0
- polyfile/magic_defs/intel +310 -0
- polyfile/magic_defs/interleaf +9 -0
- polyfile/magic_defs/island +10 -0
- polyfile/magic_defs/ispell +63 -0
- polyfile/magic_defs/isz +15 -0
- polyfile/magic_defs/java +52 -0
- polyfile/magic_defs/javascript +171 -0
- polyfile/magic_defs/jpeg +252 -0
- polyfile/magic_defs/json +8 -0
- polyfile/magic_defs/karma +9 -0
- polyfile/magic_defs/kde +11 -0
- polyfile/magic_defs/keepass +20 -0
- polyfile/magic_defs/kerberos +45 -0
- polyfile/magic_defs/kicad +85 -0
- polyfile/magic_defs/kml +34 -0
- polyfile/magic_defs/lammps +64 -0
- polyfile/magic_defs/lecter +6 -0
- polyfile/magic_defs/lex +12 -0
- polyfile/magic_defs/lif +50 -0
- polyfile/magic_defs/linux +557 -0
- polyfile/magic_defs/lisp +78 -0
- polyfile/magic_defs/llvm +22 -0
- polyfile/magic_defs/locoscript +12 -0
- polyfile/magic_defs/lua +31 -0
- polyfile/magic_defs/luks +126 -0
- polyfile/magic_defs/m4 +11 -0
- polyfile/magic_defs/mach +303 -0
- polyfile/magic_defs/macintosh +505 -0
- polyfile/magic_defs/macos +7 -0
- polyfile/magic_defs/magic +10 -0
- polyfile/magic_defs/magic.mgc +0 -0
- polyfile/magic_defs/mail.news +132 -0
- polyfile/magic_defs/make +21 -0
- polyfile/magic_defs/map +413 -0
- polyfile/magic_defs/maple +109 -0
- polyfile/magic_defs/marc21 +30 -0
- polyfile/magic_defs/mathcad +8 -0
- polyfile/magic_defs/mathematica +188 -0
- polyfile/magic_defs/matroska +17 -0
- polyfile/magic_defs/mcrypt +52 -0
- polyfile/magic_defs/measure +44 -0
- polyfile/magic_defs/mercurial +13 -0
- polyfile/magic_defs/metastore +8 -0
- polyfile/magic_defs/meteorological +53 -0
- polyfile/magic_defs/microfocus +21 -0
- polyfile/magic_defs/mime +9 -0
- polyfile/magic_defs/mips +120 -0
- polyfile/magic_defs/mirage +8 -0
- polyfile/magic_defs/misctools +140 -0
- polyfile/magic_defs/mkid +11 -0
- polyfile/magic_defs/mlssa +8 -0
- polyfile/magic_defs/mmdf +6 -0
- polyfile/magic_defs/modem +92 -0
- polyfile/magic_defs/modulefile +9 -0
- polyfile/magic_defs/motorola +71 -0
- polyfile/magic_defs/mozilla +37 -0
- polyfile/magic_defs/msdos +2304 -0
- polyfile/magic_defs/msooxml +68 -0
- polyfile/magic_defs/msvc +222 -0
- polyfile/magic_defs/msx +309 -0
- polyfile/magic_defs/mup +24 -0
- polyfile/magic_defs/music +17 -0
- polyfile/magic_defs/nasa +7 -0
- polyfile/magic_defs/natinst +24 -0
- polyfile/magic_defs/ncr +49 -0
- polyfile/magic_defs/neko +12 -0
- polyfile/magic_defs/netbsd +251 -0
- polyfile/magic_defs/netscape +26 -0
- polyfile/magic_defs/netware +11 -0
- polyfile/magic_defs/news +13 -0
- polyfile/magic_defs/nifty +202 -0
- polyfile/magic_defs/nim-lang +29 -0
- polyfile/magic_defs/nitpicker +14 -0
- polyfile/magic_defs/numpy +9 -0
- polyfile/magic_defs/oasis +12 -0
- polyfile/magic_defs/ocaml +14 -0
- polyfile/magic_defs/octave +6 -0
- polyfile/magic_defs/ole2compounddocs +760 -0
- polyfile/magic_defs/olf +98 -0
- polyfile/magic_defs/openfst +17 -0
- polyfile/magic_defs/opentimestamps +16 -0
- polyfile/magic_defs/oric +16 -0
- polyfile/magic_defs/os2 +186 -0
- polyfile/magic_defs/os400 +39 -0
- polyfile/magic_defs/os9 +80 -0
- polyfile/magic_defs/osf1 +10 -0
- polyfile/magic_defs/palm +156 -0
- polyfile/magic_defs/parix +13 -0
- polyfile/magic_defs/parrot +22 -0
- polyfile/magic_defs/pascal +39 -0
- polyfile/magic_defs/pbf +11 -0
- polyfile/magic_defs/pbm +8 -0
- polyfile/magic_defs/pc88 +24 -0
- polyfile/magic_defs/pc98 +77 -0
- polyfile/magic_defs/pci_ids +116 -0
- polyfile/magic_defs/pcjr +8 -0
- polyfile/magic_defs/pdf +51 -0
- polyfile/magic_defs/pdp +42 -0
- polyfile/magic_defs/perl +100 -0
- polyfile/magic_defs/pgf +52 -0
- polyfile/magic_defs/pgp +581 -0
- polyfile/magic_defs/pgp-binary-keys +388 -0
- polyfile/magic_defs/pkgadd +7 -0
- polyfile/magic_defs/plan9 +25 -0
- polyfile/magic_defs/playdate +57 -0
- polyfile/magic_defs/plus5 +18 -0
- polyfile/magic_defs/pmem +46 -0
- polyfile/magic_defs/polyfile_zip +5 -0
- polyfile/magic_defs/polyml +23 -0
- polyfile/magic_defs/printer +269 -0
- polyfile/magic_defs/project +10 -0
- polyfile/magic_defs/psdbms +14 -0
- polyfile/magic_defs/psl +14 -0
- polyfile/magic_defs/pulsar +13 -0
- polyfile/magic_defs/puzzle +17 -0
- polyfile/magic_defs/pwsafe +14 -0
- polyfile/magic_defs/pyramid +12 -0
- polyfile/magic_defs/python +305 -0
- polyfile/magic_defs/qt +30 -0
- polyfile/magic_defs/revision +66 -0
- polyfile/magic_defs/riff +840 -0
- polyfile/magic_defs/rinex +44 -0
- polyfile/magic_defs/ringdove +45 -0
- polyfile/magic_defs/rpi +52 -0
- polyfile/magic_defs/rpm +45 -0
- polyfile/magic_defs/rpmsg +7 -0
- polyfile/magic_defs/rst +11 -0
- polyfile/magic_defs/rtf +94 -0
- polyfile/magic_defs/ruby +55 -0
- polyfile/magic_defs/rust +21 -0
- polyfile/magic_defs/sc +7 -0
- polyfile/magic_defs/sccs +24 -0
- polyfile/magic_defs/scientific +144 -0
- polyfile/magic_defs/securitycerts +6 -0
- polyfile/magic_defs/selinux +24 -0
- polyfile/magic_defs/sendmail +37 -0
- polyfile/magic_defs/sequent +42 -0
- polyfile/magic_defs/sereal +35 -0
- polyfile/magic_defs/sgi +144 -0
- polyfile/magic_defs/sgml +161 -0
- polyfile/magic_defs/sharc +23 -0
- polyfile/magic_defs/sinclair +40 -0
- polyfile/magic_defs/sisu +18 -0
- polyfile/magic_defs/sketch +6 -0
- polyfile/magic_defs/smalltalk +25 -0
- polyfile/magic_defs/smile +34 -0
- polyfile/magic_defs/sniffer +482 -0
- polyfile/magic_defs/softquad +40 -0
- polyfile/magic_defs/sosi +40 -0
- polyfile/magic_defs/spec +21 -0
- polyfile/magic_defs/spectrum +184 -0
- polyfile/magic_defs/sql +288 -0
- polyfile/magic_defs/ssh +39 -0
- polyfile/magic_defs/ssl +20 -0
- polyfile/magic_defs/statistics +45 -0
- polyfile/magic_defs/subtitle +38 -0
- polyfile/magic_defs/sun +141 -0
- polyfile/magic_defs/svf +5 -0
- polyfile/magic_defs/sylk +36 -0
- polyfile/magic_defs/symbos +42 -0
- polyfile/magic_defs/sysex +429 -0
- polyfile/magic_defs/tcl +29 -0
- polyfile/magic_defs/teapot +6 -0
- polyfile/magic_defs/terminfo +63 -0
- polyfile/magic_defs/tex +141 -0
- polyfile/magic_defs/tgif +7 -0
- polyfile/magic_defs/ti-8x +239 -0
- polyfile/magic_defs/timezone +42 -0
- polyfile/magic_defs/tplink +95 -0
- polyfile/magic_defs/troff +38 -0
- polyfile/magic_defs/tuxedo +8 -0
- polyfile/magic_defs/typeset +8 -0
- polyfile/magic_defs/uf2 +72 -0
- polyfile/magic_defs/unicode +15 -0
- polyfile/magic_defs/unisig +12 -0
- polyfile/magic_defs/unknown +34 -0
- polyfile/magic_defs/usd +21 -0
- polyfile/magic_defs/uterus +16 -0
- polyfile/magic_defs/uuencode +28 -0
- polyfile/magic_defs/vacuum-cleaner +54 -0
- polyfile/magic_defs/varied.out +46 -0
- polyfile/magic_defs/varied.script +21 -0
- polyfile/magic_defs/vax +32 -0
- polyfile/magic_defs/vicar +17 -0
- polyfile/magic_defs/virtual +307 -0
- polyfile/magic_defs/virtutech +12 -0
- polyfile/magic_defs/visx +32 -0
- polyfile/magic_defs/vms +30 -0
- polyfile/magic_defs/vmware +6 -0
- polyfile/magic_defs/vorbis +155 -0
- polyfile/magic_defs/vxl +14 -0
- polyfile/magic_defs/warc +16 -0
- polyfile/magic_defs/weak +16 -0
- polyfile/magic_defs/web +18 -0
- polyfile/magic_defs/webassembly +17 -0
- polyfile/magic_defs/windows +1811 -0
- polyfile/magic_defs/wireless +7 -0
- polyfile/magic_defs/wordprocessors +630 -0
- polyfile/magic_defs/wsdl +23 -0
- polyfile/magic_defs/x68000 +25 -0
- polyfile/magic_defs/xdelta +13 -0
- polyfile/magic_defs/xenix +106 -0
- polyfile/magic_defs/xilinx +58 -0
- polyfile/magic_defs/xo65 +37 -0
- polyfile/magic_defs/xwindows +43 -0
- polyfile/magic_defs/yara +17 -0
- polyfile/magic_defs/zfs +96 -0
- polyfile/magic_defs/zilog +12 -0
- polyfile/magic_defs/zip +126 -0
- polyfile/magic_defs/zyxel +17 -0
- polyfile/nes.py +144 -0
- polyfile/nitf.py +15 -0
- polyfile/pdf.py +1264 -0
- polyfile/pickles.py +45 -0
- polyfile/polyfile.py +409 -0
- polyfile/profiling.py +115 -0
- polyfile/repl.py +624 -0
- polyfile/search.py +310 -0
- polyfile/serialization.py +323 -0
- polyfile/structmatcher.py +46 -0
- polyfile/structs.py +281 -0
- polyfile/templates/download.js +162 -0
- polyfile/templates/hexdump.css +268 -0
- polyfile/templates/hexdump.js +756 -0
- polyfile/templates/jquery-3.4.1.min.js +2 -0
- polyfile/templates/template.html +119 -0
- polyfile/wildcards.py +62 -0
- polyfile/zipmatcher.py +183 -0
- polyfile_weave-0.5.5.dist-info/METADATA +173 -0
- polyfile_weave-0.5.5.dist-info/RECORD +585 -0
- polyfile_weave-0.5.5.dist-info/WHEEL +5 -0
- polyfile_weave-0.5.5.dist-info/entry_points.txt +2 -0
- polyfile_weave-0.5.5.dist-info/licenses/LICENSE +202 -0
- polyfile_weave-0.5.5.dist-info/top_level.txt +2 -0
- polymerge/__init__.py +1 -0
- polymerge/__main__.py +296 -0
- polymerge/cfg.py +127 -0
- polymerge/polymerge.py +227 -0
- 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,)
|