Files
altium-render-engine/backend/app/parser/pcb_container.py
T
2026-11-09 12:34:50 +03:30

45 خطوط
2.1 KiB
Python

"""Cheap bounded PCB envelope validation; complete decoding stays in the worker."""
import io
import struct
import olefile
from .record_decoder import ParseError
from .pcb_binary import Reader, text_records
SIGNATURE = b'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1'
def identify_pcb(data):
if not data.startswith(SIGNATURE):
raise ParseError('PcbDoc must be an OLE compound document')
try:
with olefile.OleFileIO(io.BytesIO(data), raise_defects=olefile.DEFECT_INCORRECT) as ole:
if len(ole.listdir()) > 1024:
raise ParseError('Excessive PCB stream count')
for name, limit in [('FileHeaderSix', 4096), ('Board6/Data', 4 * 1024**2)]:
if not ole.exists(name) or ole.get_type(name) != 2:
raise ParseError(f'Missing PCB stream {name}')
if ole.get_size(name) > limit:
raise ParseError(f'PCB stream {name} exceeds size limit')
reader = Reader(ole.openstream('FileHeaderSix').read(), 'FileHeaderSix')
length = reader.read('I'); envelope = reader.pascal()
if length != len(envelope) or envelope != 'PCB 6.0 Binary File':
raise ParseError('Unsupported PCB file envelope')
records = text_records(ole.openstream('Board6/Data').read(), 'Board6')
if len(records) != 1 or records[0].get('KIND') != 'Protel_Advanced_PCB':
raise ParseError('Invalid Board6 identification')
if records[0].get('VERSION') not in ('5.0', '5.01', '6.0'):
raise ParseError('Unsupported PCB board version')
except (OSError, IOError, ValueError, IndexError, struct.error) as exc:
if isinstance(exc, ParseError): raise
raise ParseError('Invalid PCB compound document') from exc
def contains_pcb(data):
"""Reject PCB data renamed to SchDoc without altering legacy corrupt-file handling."""
if not data.startswith(SIGNATURE): return False
try:
with olefile.OleFileIO(io.BytesIO(data)) as ole:
return ole.exists('Board6/Data')
except (OSError, ValueError, IndexError, struct.error):
return False