Reject oversized step-repeat expansions
This commit is contained in:
parent
e3674de08d
commit
736107f7a4
2 changed files with 31 additions and 7 deletions
|
|
@ -599,6 +599,8 @@ class GerberParser:
|
|||
NUMBER = r"[\+-]?\d+"
|
||||
DECIMAL = r"[\+-]?\d+([.]?\d+)?"
|
||||
NAME = r"[a-zA-Z_$\.][a-zA-Z_$\.0-9+\-]+"
|
||||
MAX_STEP_REPEAT_INSTANCES = 100000
|
||||
MAX_STEP_REPEAT_RESULT_OBJECTS = 100000
|
||||
|
||||
STATEMENT_REGEXES = {
|
||||
'coord': fr"(G0?[123]|G74|G75|G54|G55)?\s*(?:X\+?(-?)({NUMBER}))?(?:Y\+?(-?)({NUMBER}))?" \
|
||||
|
|
@ -1095,18 +1097,23 @@ class GerberParser:
|
|||
i, j = float(match['I']), float(match['J'])
|
||||
if x < 1 or y < 1:
|
||||
raise SyntaxError('SR step-repeat X and Y values must be at least 1')
|
||||
if x * y > self.MAX_STEP_REPEAT_INSTANCES:
|
||||
raise SyntaxError('SR step-repeat expands to too many instances')
|
||||
|
||||
self.step_repeat_coords = [
|
||||
(i*nx, j*ny)
|
||||
for nx in range(x) for ny in range(y)] # the order matters here, cf. the spec
|
||||
self.step_repeat_coords = (x, y, i, j)
|
||||
self.step_repeat_objects = []
|
||||
|
||||
else:
|
||||
x, y, i, j = self.step_repeat_coords
|
||||
if len(self.step_repeat_objects) * x * y > self.MAX_STEP_REPEAT_RESULT_OBJECTS:
|
||||
raise SyntaxError('SR step-repeat expands to too many objects')
|
||||
|
||||
for obj in self.step_repeat_objects:
|
||||
for dx, dy in self.step_repeat_coords:
|
||||
new_obj = copy.copy(obj)
|
||||
new_obj.offset(dx, dy)
|
||||
self.target.objects.append(new_obj)
|
||||
for nx in range(x):
|
||||
for ny in range(y):
|
||||
new_obj = copy.copy(obj)
|
||||
new_obj.offset(i * nx, j * ny)
|
||||
self.target.objects.append(new_obj)
|
||||
self.step_repeat_coords = None
|
||||
self.step_repeat_objects = None
|
||||
|
||||
|
|
|
|||
|
|
@ -637,6 +637,23 @@ def test_syntax_error():
|
|||
assert 'test_syntax_error.gbr' in exc_info.value.msg
|
||||
assert '7' in exc_info.value.msg # lineno
|
||||
|
||||
@filter_syntax_warnings
|
||||
def test_step_repeat_rejects_huge_instance_counts():
|
||||
data = '\n'.join([
|
||||
'G04 test*',
|
||||
'%MOIN*%',
|
||||
'%FSLAX24Y24*%',
|
||||
'%ADD10C,0.0100*%',
|
||||
'%SRX1000Y1000I1.0J1.0*%',
|
||||
'D10*',
|
||||
'X0000Y0000D03*',
|
||||
'%SR*%',
|
||||
'M02*',
|
||||
])
|
||||
|
||||
with pytest.raises(SyntaxError, match='too many instances'):
|
||||
GerberFile.from_string(data)
|
||||
|
||||
@filter_syntax_warnings
|
||||
@pytest.mark.parametrize('reference', MIN_REFERENCE_FILES, indirect=True)
|
||||
def test_invert_polarity(reference, tmpfile, img_support):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue