"""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')