fix(parse): build array String() without recursion

utils.generation_params converted nested arrays to strings recursively,
so a crafted file with a value nested about 900 arrays deep raised
RecursionError, where the browser parser returns a result. The join now
runs on an explicit stack. A JS-parity case with 900-deep values pins it.
This commit is contained in:
Vito Sansevero
2026-10-19 21:34:47 -07:00
parent 36564b4767
commit b0ca3ced5f
4 changed files with 64 additions and 1 deletions
+24 -1
View File
@@ -217,10 +217,33 @@ def _js_string(value):
if isinstance(value, str):
return value
if isinstance(value, list):
return ",".join("" if _nullish(item) else _js_string(item) for item in value)
return _array_string(value)
return "[object Object]"
def _array_string(value):
"""``String(array)``: ``join(",")`` applied to nested arrays, on an explicit stack.
null and undefined elements join as "". A crafted file can nest arrays far
deeper than the Python stack allows, so this never recurses.
"""
out = []
stack = [(value, 0)]
while stack:
items, index = stack.pop()
if index == len(items):
continue
if index:
out.append(",")
stack.append((items, index + 1))
item = items[index]
if isinstance(item, list):
stack.append((item, 0))
elif not _nullish(item):
out.append(_js_string(item))
return "".join(out)
def _key(value):
return value if isinstance(value, str) else _js_string(value)