Merge pull request #3679 from fonttools/cff2-specializer-maxStack
[CFF2] specializer fix stack overflow
This commit is contained in:
commit
dafb6d26a0
@ -446,9 +446,9 @@ def _convertToBlendCmds(args):
|
|||||||
i = 0
|
i = 0
|
||||||
while i < num_args:
|
while i < num_args:
|
||||||
arg = args[i]
|
arg = args[i]
|
||||||
|
i += 1
|
||||||
if not isinstance(arg, list):
|
if not isinstance(arg, list):
|
||||||
new_args.append(arg)
|
new_args.append(arg)
|
||||||
i += 1
|
|
||||||
stack_use += 1
|
stack_use += 1
|
||||||
else:
|
else:
|
||||||
prev_stack_use = stack_use
|
prev_stack_use = stack_use
|
||||||
@ -458,13 +458,8 @@ def _convertToBlendCmds(args):
|
|||||||
# up to the max stack limit.
|
# up to the max stack limit.
|
||||||
num_sources = len(arg) - 1
|
num_sources = len(arg) - 1
|
||||||
blendlist = [arg]
|
blendlist = [arg]
|
||||||
i += 1
|
|
||||||
stack_use += 1 + num_sources # 1 for the num_blends arg
|
stack_use += 1 + num_sources # 1 for the num_blends arg
|
||||||
while (i < num_args) and isinstance(args[i], list):
|
|
||||||
blendlist.append(args[i])
|
|
||||||
i += 1
|
|
||||||
stack_use += num_sources
|
|
||||||
if stack_use + num_sources > maxStackLimit:
|
|
||||||
# if we are here, max stack is the CFF2 max stack.
|
# if we are here, max stack is the CFF2 max stack.
|
||||||
# I use the CFF2 max stack limit here rather than
|
# I use the CFF2 max stack limit here rather than
|
||||||
# the 'maxstack' chosen by the client, as the default
|
# the 'maxstack' chosen by the client, as the default
|
||||||
@ -472,7 +467,17 @@ def _convertToBlendCmds(args):
|
|||||||
# the other operators, this just produces a little less
|
# the other operators, this just produces a little less
|
||||||
# optimization, but here it puts a hard (and low) limit
|
# optimization, but here it puts a hard (and low) limit
|
||||||
# on the number of source fonts that can be used.
|
# on the number of source fonts that can be used.
|
||||||
break
|
#
|
||||||
|
# Make sure the stack depth does not exceed (maxstack - 1), so
|
||||||
|
# that subroutinizer can insert subroutine calls at any point.
|
||||||
|
while (
|
||||||
|
(i < num_args)
|
||||||
|
and isinstance(args[i], list)
|
||||||
|
and stack_use + num_sources < maxStackLimit
|
||||||
|
):
|
||||||
|
blendlist.append(args[i])
|
||||||
|
i += 1
|
||||||
|
stack_use += num_sources
|
||||||
# blendList now contains as many single blend tuples as can be
|
# blendList now contains as many single blend tuples as can be
|
||||||
# combined without exceeding the CFF2 stack limit.
|
# combined without exceeding the CFF2 stack limit.
|
||||||
num_blends = len(blendlist)
|
num_blends = len(blendlist)
|
||||||
@ -504,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,
|
||||||
@ -746,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]
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user