29 خطوط
1.4 KiB
Python
29 خطوط
1.4 KiB
Python
import io
|
|
import struct
|
|
import olefile
|
|
from .record_decoder import ParseError, binary_records, ascii_records, detect_format
|
|
|
|
MAX_STREAM_BYTES = 32 * 1024 * 1024
|
|
MAX_TOTAL_BYTES = 64 * 1024 * 1024
|
|
|
|
def read_document(data):
|
|
fmt=detect_format(data)
|
|
if fmt=='ascii':
|
|
return fmt,[],ascii_records(data),[]
|
|
try:
|
|
with olefile.OleFileIO(io.BytesIO(data),raise_defects=olefile.DEFECT_INCORRECT) as ole:
|
|
entries=ole.listdir(streams=True,storages=False)
|
|
if len(entries)>256: raise ParseError('Too many OLE streams')
|
|
streams=[{'name':'/'.join(p),'size':ole.get_size(p)} for p in entries]
|
|
if any(s['size']>MAX_STREAM_BYTES for s in streams) or sum(s['size'] for s in streams)>MAX_TOTAL_BYTES:
|
|
raise ParseError('OLE stream size limit exceeded')
|
|
if not ole.exists('FileHeader') or ole.get_type('FileHeader')!=2:
|
|
raise ParseError('OLE container has no FileHeader stream')
|
|
main=binary_records(ole.openstream('FileHeader').read(),'FileHeader')
|
|
extra=[]
|
|
if ole.exists('Additional') and ole.get_type('Additional')==2:
|
|
extra=binary_records(ole.openstream('Additional').read(),'Additional')
|
|
return fmt,streams,main,extra
|
|
except (OSError,IOError,ValueError,IndexError,struct.error) as exc:
|
|
raise ParseError(f'Invalid OLE schematic: {exc}') from exc
|