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