@@ -0,0 +1,44 @@
|
||||
"""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
|
||||
مرجع در شماره جدید
مسدود کردن کاربر