Skip to content

Commit 7e837a3

Browse files
committed
limits
1 parent 01361ad commit 7e837a3

3 files changed

Lines changed: 44 additions & 0 deletions

File tree

qualtran/l1/_eval.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ def eval_carg_nodes(
4747
args: The evaluated positional arguments
4848
kwargs: The evaluated keyword arguments
4949
"""
50+
if len(cargs) > 1_000 and safe:
51+
raise ValueError("Too many arguments for safe=True loading.")
5052
args: List[Any] = []
5153
kwargs: Dict[str, Any] = {}
5254
kwarg_only = False
@@ -153,6 +155,8 @@ def eval_cvalue_node(node: CValueNode, *, safe: bool = True) -> Any:
153155

154156
# Recurse on tuples
155157
if isinstance(node, TupleNode):
158+
if len(node.items) > 1_000 and safe:
159+
raise ValueError("Too many elements for safe=True tuple.")
156160
return tuple(eval_cvalue_node(n, safe=safe) for n in node.items)
157161

158162
# Objects

qualtran/l1/_eval_test.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,17 @@ def test_imported_bloq_class():
208208
def test_eval_cvalue_node_type_error():
209209
with pytest.raises(TypeError, match="Unknown AST node type"):
210210
eval_cvalue_node("just a string") # type: ignore[arg-type]
211+
212+
213+
def test_too_many_args():
214+
node = CObjectNode(name='Test', cargs=[CArgNode(None, LiteralNode(5))] * 1_001)
215+
216+
with pytest.raises(ValueError, match=r'Too many.*'):
217+
_ = eval_cvalue_node(node, safe=True)
218+
219+
220+
def test_too_many_values():
221+
node = TupleNode([LiteralNode(5)] * 1_001)
222+
223+
with pytest.raises(ValueError, match=r'Too many.*'):
224+
_ = eval_cvalue_node(node, safe=True)

qualtran/l1/_parse_test.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import io
16+
import sys
1617

1718
import pytest
1819

@@ -216,3 +217,28 @@ def test_parse_cvalue_cobject():
216217
node = parser.parse_cvalue()
217218
assert isinstance(node, CObjectNode)
218219
assert node.name == 'MyBloq'
220+
221+
222+
def test_parse_nested():
223+
from qualtran.l1._eval import eval_cvalue_node
224+
225+
n = 100
226+
str = '(' * n + '5,' + ')' * n
227+
tokens = tokenize(str)
228+
parser = QualtranL1Parser(tokens)
229+
ast = parser.parse_cvalue()
230+
result = eval_cvalue_node(ast)
231+
232+
should_be = 5
233+
for i in range(n):
234+
should_be = (should_be,)
235+
assert result == should_be
236+
237+
238+
def test_parse_too_nested():
239+
n = sys.getrecursionlimit() + 1
240+
str = '(' * n + '5,' + ')' * n
241+
tokens = tokenize(str)
242+
parser = QualtranL1Parser(tokens)
243+
with pytest.raises(RecursionError):
244+
ast = parser.parse_cvalue()

0 commit comments

Comments
 (0)