[cffLib.specializer] Fix more stack-overflow opportunity
I think it's solid now.
This commit is contained in:
parent
2e96d81b05
commit
bb7a29e81a
@ -509,6 +509,19 @@ def _addArgs(a, b):
|
|||||||
return a + b
|
return a + b
|
||||||
|
|
||||||
|
|
||||||
|
def _argsStackUse(args):
|
||||||
|
stackLen = 0
|
||||||
|
maxLen = 0
|
||||||
|
for arg in args:
|
||||||
|
if type(arg) is list:
|
||||||
|
# Blended arg
|
||||||
|
maxLen = max(maxLen, stackLen + _argsStackUse(arg))
|
||||||
|
stackLen += arg[-1]
|
||||||
|
else:
|
||||||
|
stackLen += 1
|
||||||
|
return max(stackLen, maxLen)
|
||||||
|
|
||||||
|
|
||||||
def specializeCommands(
|
def specializeCommands(
|
||||||
commands,
|
commands,
|
||||||
ignoreErrors=False,
|
ignoreErrors=False,
|
||||||
@ -751,7 +764,7 @@ def specializeCommands(
|
|||||||
|
|
||||||
# Make sure the stack depth does not exceed (maxstack - 1), so
|
# Make sure the stack depth does not exceed (maxstack - 1), so
|
||||||
# that subroutinizer can insert subroutine calls at any point.
|
# that subroutinizer can insert subroutine calls at any point.
|
||||||
if new_op and len(args1) + len(args2) < maxstack:
|
if new_op and _argsStackUse(args1) + _argsStackUse(args2) < maxstack:
|
||||||
commands[i - 1] = (new_op, args1 + args2)
|
commands[i - 1] = (new_op, args1 + args2)
|
||||||
del commands[i]
|
del commands[i]
|
||||||
|
|
||||||
|
@ -585,17 +585,19 @@ class CFFSpecializeProgramTest:
|
|||||||
|
|
||||||
# maxstack CFF2=513, specializer uses up to 512
|
# maxstack CFF2=513, specializer uses up to 512
|
||||||
def test_maxstack_blends(self):
|
def test_maxstack_blends(self):
|
||||||
getNumRegions = lambda iv: 15
|
numRegions = 15
|
||||||
blend_one = "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 blend"
|
numOps = 2000
|
||||||
|
getNumRegions = lambda iv: numRegions
|
||||||
|
blend_one = " ".join([str(i) for i in range(1 + numRegions)] + ["1", "blend"])
|
||||||
operands = " ".join([blend_one] * 6)
|
operands = " ".join([blend_one] * 6)
|
||||||
operator = "rrcurveto"
|
operator = "rrcurveto"
|
||||||
charstr = " ".join([operands, operator] * 10)
|
charstr = " ".join([operands, operator] * numOps)
|
||||||
expected = charstr
|
expected = charstr
|
||||||
specialized = charstr_specialize(
|
specialized = charstr_specialize(
|
||||||
charstr, getNumRegions=getNumRegions, maxstack=maxStack
|
charstr, getNumRegions=getNumRegions, maxstack=maxStack
|
||||||
)
|
)
|
||||||
stack_use = charstr_stack_use(specialized, getNumRegions=getNumRegions)
|
stack_use = charstr_stack_use(specialized, getNumRegions=getNumRegions)
|
||||||
assert stack_use < maxStack
|
assert maxStack - numRegions < stack_use < maxStack
|
||||||
|
|
||||||
|
|
||||||
class CFF2VFTestSpecialize(DataFilesHandler):
|
class CFF2VFTestSpecialize(DataFilesHandler):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user