Studio: stop the Gemma tool-call array parser hanging on malformed input

This commit is contained in:
Daniel Han 2026-07-06 06:59:31 +00:00
parent ade6613e99
commit 698e76e323
2 changed files with 26 additions and 1 deletions

View file

@ -772,7 +772,13 @@ def _gemma_parse_value(text: str, i: int):
if body[k] in " \t\n\r,":
k += 1
continue
v, k = _gemma_parse_value(body, k)
v, next_k = _gemma_parse_value(body, k)
if next_k <= k:
# Malformed array (e.g. a stray ``}`` with no opening
# ``{``): the primitive branch consumed nothing, so stop
# rather than spin forever.
break
k = next_k
items.append(v)
return items, j + 1
# Primitive: number / true/false/null / bare identifier.

View file

@ -419,6 +419,25 @@ class TestParserMultiFormat:
result = parse_tool_calls_from_text(text)
assert isinstance(result, list)
def test_gemma4_malformed_array_terminates(self):
# Regression: a stray ``}`` inside a Gemma array (unbalanced
# braces) once spun the list loop forever because
# ``_gemma_parse_value`` returned without advancing the index.
# Parsing must terminate on this malformed input.
import threading
text = "<|tool_call>call:foo{items:[1}}<tool_call|>"
box: dict = {}
def _run():
box["result"] = parse_tool_calls_from_text(text)
worker = threading.Thread(target = _run, daemon = True)
worker.start()
worker.join(timeout = 5)
assert not worker.is_alive(), "Gemma parser hung on malformed array input"
assert isinstance(box["result"], list)
def test_gemma4_strip_markup_final(self):
text = "<|tool_call>call:foo{x:1}<tool_call|>"
assert strip_tool_markup(text, final = True) == ""