Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def createFields(self):
yield BitmapInfoHeader(self, "header")
# Read palette if needed
nb_color = self.header["nb_color"].value
if self.header["bpp"].value == 8:
nb_color = 256
if nb_color != 0:
yield PaletteRGBA(self, "palette", nb_color)
# Read pixels
size = self.header["size"].value - self.current_size // 8
yield RawBytes(self, "pixels", size, "Image pixels")
class IcoFile(Parser):
endian = LITTLE_ENDIAN
PARSER_TAGS = {
"id": "ico",
"category": "image",
"file_ext": ("ico", "cur"),
"mime": ("image/x-ico",),
"min_size": (22 + 40) * 8,
# "magic": (
# (b"\0\0\1\0", 0), # Icon
# (b"\0\0\2\0", 0), # Cursor
# ),
"magic_regex": ((
# signature=0, type=(1|2), count in 1..20,
b"\0\0[\1\2]\0[\x01-\x14]."
# size=(16x16|32x32|48x48|64x64),
b"(\x10\x10|\x20\x20|\x30\x30|\x40\x40)"
# Prefer Win32 filename
fileattr = fn
break
else:
fileattr = fn
if fileattr:
if 'filename' in fileattr:
text += ' "%s"' % fileattr["filename"].value
text += ' (%s)' % fileattr["real_size"].display
if "standard_info/file_attr" in self:
text += ', %s' % self["standard_info/file_attr"].display
return text
class NTFS(Parser):
MAGIC = b"\xEB\x52\x90NTFS "
PARSER_TAGS = {
"id": "ntfs",
"category": "file_system",
"description": "NTFS file system",
"min_size": 1024 * 8,
"magic": ((MAGIC, 0),),
}
endian = LITTLE_ENDIAN
_cluster_size = None
def validate(self):
if self.stream.readBytes(0, len(self.MAGIC)) != self.MAGIC:
return "Invalid magic string"
err = self["mbr/bios"].validate()
if err:
if padding:
yield PaddingBits(self, "padding[]", padding)
self.parent.uncompressed_data = self["deflate_block"].uncomp_data
elif compr_method == 2: # Quantum
yield RawBytes(self, "compr_data", self["size"].value, "Compressed Folder Data")
elif compr_method == 3: # LZX
group = getattr(self.parent.folder, "lzx_group", None)
field = CustomFragment(
self, "data", self["size"].value * 8, LZXStream, "LZX data fragment", group)
if group is None:
field.group.args["compr_level"] = self.parent.folder["compr_level"].value
self.parent.folder.lzx_group = field.group
yield field
class FolderParser(Parser):
endian = LITTLE_ENDIAN
def createFields(self):
for file in sorted(self.files, key=lambda x: x["folder_offset"].value):
padding = self.seekByte(file["folder_offset"].value)
if padding:
yield padding
yield RawBytes(self, "file[]", file["filesize"].value, file.description)
class FolderData(FieldSet):
def __init__(self, parent, name, folder, files, *args, **kwargs):
FieldSet.__init__(self, parent, name, *args, **kwargs)
def createInputStream(cis, source=None, **args):
class CharInfo(FieldSet):
static_size = 16 * 8
def createFields(self):
yield UInt32(self, "data_offset")
yield UInt8(self, "logical_width")
yield UInt8(self, "unknown[]")
yield UInt8(self, "unknown[]")
yield UInt8(self, "unknown[]")
yield UInt32(self, "width_pixels")
yield UInt32(self, "height_pixels")
class LafFile(Parser):
PARSER_TAGS = {
"id": "lucasarts_font",
"category": "game",
"file_ext": ("laf",),
"min_size": 32 * 8,
"description": "LucasArts Font"
}
endian = LITTLE_ENDIAN
def validate(self):
if self["num_chars"].value != 256:
return "Invalid number of characters (%u)" % self["num_chars"].value
if self["first_char_code"].value != 0:
return "Invalid of code of first character code (%u)" % self["first_char_code"].value
if self["last_char_code"].value != 255:
====================== 8< ============================
TODO parser.
Author: TODO TODO
Creation date: YYYY-mm-DD
"""
# TODO: Just keep what you need
from hachoir.parser import Parser
# from hachoir.field import (ParserError,
# UInt8, UInt16, UInt32, String, RawBytes)
# from hachoir.core.endian import LITTLE_ENDIAN, BIG_ENDIAN
class TODOFile(Parser):
PARSER_TAGS = {
"id": "TODO",
"category": "TODO", # "archive", "audio", "container", ...
# TODO: Example ("bmp",) to parse the file "image.bmp"
"file_ext": ("TODO",),
"mime": ("TODO",), # TODO: Example: "image/png"
# TODO: Minimum file size (x bits, or x*8 in bytes)
"min_size": 0,
"description": "TODO", # TODO: Example: "A bitmap picture"
}
# TODO: Choose between little or big endian
# endian = LITTLE_ENDIAN
# endian = BIG_ENDIAN
def validate(self):
yield UInt8(self, "background", "Background color")
field = UInt8(self, "pixel_aspect_ratio")
if field.value:
field._description = "Pixel aspect ratio: %f (stored as %i)" % (
(field.value + 15) / 64., field.value)
else:
field._description = "Pixel aspect ratio: not specified"
yield field
def createDescription(self):
colors = 1 << (self["size_global_map"].value + 1)
return "Screen descriptor: %ux%u pixels %u colors" \
% (self["width"].value, self["height"].value, colors)
class GifFile(Parser):
endian = LITTLE_ENDIAN
separator_name = {
"!": "Extension",
",": "Image",
";": "Terminator"
}
PARSER_TAGS = {
"id": "gif",
"category": "image",
"file_ext": ("gif",),
"mime": ("image/gif",),
# signature + screen + separator + image
"min_size": (6 + 7 + 1 + 9) * 8,
"magic": ((b"GIF87a", 0), (b"GIF89a", 0)),
"description": "GIF picture"
}
# text = ["%1.6f: " % ts]
text = ["%s: " % ts]
if "icmp" in self:
text.append(self["icmp"].description)
elif "tcp" in self:
text.append(self["tcp"].description)
elif "udp" in self:
text.append(self["udp"].description)
elif "arp" in self:
text.append(self["arp"].description)
else:
text.append("Packet")
return "".join(text)
class TcpdumpFile(Parser):
PARSER_TAGS = {
"id": "tcpdump",
"category": "misc",
"min_size": 24 * 8,
"description": "Tcpdump file (network)",
"magic": ((b"\xd4\xc3\xb2\xa1", 0),),
}
endian = LITTLE_ENDIAN
LINK_TYPE = {
1: ("ethernet", Ethernet),
113: ("unicast", Unicast),
}
LINK_TYPE_DESC = createDict(LINK_TYPE, 0)
def validate(self):
return 0
def createDescription(self):
if self.isEmpty():
desc = "(terminator, empty header)"
else:
filename = self["name"].value
if self["prefix"].value:
filename = self["prefix"].value + '/' + filename
filesize = humanFilesize(self.getOctal("size"))
desc = "(%s: %s, %s)" % \
(filename, self["type"].display, filesize)
return "Tar File " + desc
class TarFile(Parser):
endian = BIG_ENDIAN
PARSER_TAGS = {
"id": "tar",
"category": "archive",
"file_ext": ("tar",),
"mime": ("application/x-tar", "application/x-gtar"),
"min_size": 512 * 8,
"magic": ((b"ustar \0", 257 * 8),),
"subfile": "skip",
"description": "TAR archive",
}
_sign = re.compile(b"ustar *\0|[ \0]*$")
def validate(self):
if not self._sign.match(self.stream.readBytes(257 * 8, 8)):
return "Invalid magic number"
return text
def isValid(self):
if not self["has_payload"].value and not self["has_adaptation"].value:
return "No payload and no adaptation"
pid = self["pid"].value
if (0x0002 <= pid <= 0x000f) or (0x2000 <= pid):
return "Invalid program identifier (%s)" % self["pid"].display
return ""
# M2TS 4 bytes + 188 bytes payload + 4 errors
MAX_PACKET_SIZE = 208
class MPEG_TS(Parser):
PARSER_TAGS = {
"id": "mpeg_ts",
"category": "video",
"file_ext": ("ts", "m2ts", "mts"),
"min_size": 188 * 8,
"mime": ("video/MP2T",),
"description": "MPEG-2 Transport Stream"
}
endian = BIG_ENDIAN
def is_m2ts(self):
# FIXME: detect using file content, not file name
# maybe detect sync at offset+4 bytes?
source = self.stream.source
if not(source and source.startswith("file:")):
return True
yield UInt8(self, "KeyOnStB")
yield UInt8(self, "SDD1BankA")
yield UInt8(self, "SDD1BankB")
yield UInt8(self, "SDD1BankC")
yield UInt8(self, "SDD1BankD")
yield UInt8(self, "vramread2")
yield UInt8(self, "nosprincr")
yield UInt16(self, "poamaddrs")
yield UInt8(self, "ioportval")
yield UInt8(self, "iohvlatch")
yield UInt8(self, "ppustatus")
yield PaddingBytes(self, "tempdat", 477, "Reserved/Unused")
class ZSNESFile(Parser):
PARSER_TAGS = {
"id": "zsnes",
"category": "game",
"description": "ZSNES Save State File (only version 143)",
"min_size": 3091 * 8,
"file_ext": ("zst", "zs1", "zs2", "zs3", "zs4", "zs5", "zs6",
"zs7", "zs8", "zs9")
}
endian = LITTLE_ENDIAN
def validate(self):
temp = self.stream.readBytes(0, 28)
if temp[0:26] != b"ZSNES Save State File V143":
return "Wrong header"
if ord(temp[27:28]) != 143: # extra...
return "Wrong save version %d <> 143" % temp[27:1]