Files
dsh-web/image/validate-office.py
T

30 lines
1.3 KiB
Python

"""Bounded, non-extracting Office container validation; Python stdlib only."""
import sys
import zipfile
path, ext, entries, maximum = sys.argv[1:]
if ext in ('doc', 'xls', 'ppt'):
with open(path, 'rb') as source:
if source.read(8) != bytes.fromhex('d0cf11e0a1b11ae1'):
raise ValueError('not OLE')
else:
expected = {'docx': 'word/document.xml', 'xlsx': 'xl/workbook.xml', 'pptx': 'ppt/presentation.xml'}[ext]
with zipfile.ZipFile(path) as archive:
info = archive.infolist()
names = [entry.filename for entry in info]
if len(info) > int(entries) or len(set(names)) != len(names):
raise ValueError('entry limit or duplicate')
if expected not in names or '[Content_Types].xml' not in names:
raise ValueError('format mismatch')
if sum(entry.file_size for entry in info) > int(maximum):
raise ValueError('uncompressed size limit')
total = 0
for entry in info:
if entry.flag_bits & 1:
raise ValueError('encrypted')
with archive.open(entry) as stream:
while chunk := stream.read(65536):
total += len(chunk)
if total > int(maximum):
raise ValueError('uncompressed size limit')