mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-19 05:12:19 +02:00
fix(security): eliminate induced regex denial-of-service paths
This commit is contained in:
+40
-6
@@ -1515,6 +1515,45 @@ def _parse_tool_code_block(raw: str) -> Optional[ToolBlock]:
|
||||
return ToolBlock(tool_name, content.strip())
|
||||
return None
|
||||
|
||||
_GEMMA_FALLBACK_KEY_RE = re.compile(r"\w++")
|
||||
_GEMMA_FALLBACK_COLON_RE = re.compile(r"\s*+:")
|
||||
_GEMMA_FALLBACK_BOUNDARY_RE = re.compile(r"(?<!\s)(\s*+)(?:,\s*+\w++\s*+:|})")
|
||||
|
||||
|
||||
def _iter_gemma_fallback_items(body):
|
||||
"""Preserve permissive k:v recovery with one pass over keys/boundaries."""
|
||||
boundaries = list(_GEMMA_FALLBACK_BOUNDARY_RE.finditer(body))
|
||||
boundary_index = 0
|
||||
pos = 0
|
||||
newline = body.find("\n")
|
||||
while key := _GEMMA_FALLBACK_KEY_RE.search(body, pos):
|
||||
colon = _GEMMA_FALLBACK_COLON_RE.match(body, key.end())
|
||||
if colon is None:
|
||||
pos = key.end()
|
||||
continue
|
||||
start = colon.end()
|
||||
while start < len(body) and body[start].isspace():
|
||||
start += 1
|
||||
if start < len(body) and body[start] in "\"'":
|
||||
start += 1
|
||||
while boundary_index < len(boundaries) and boundaries[boundary_index].end(1) < start:
|
||||
boundary_index += 1
|
||||
if boundary_index == len(boundaries):
|
||||
return
|
||||
boundary = boundaries[boundary_index]
|
||||
end = max(start, boundary.start())
|
||||
if 0 <= newline < start:
|
||||
newline = body.find("\n", start)
|
||||
if newline >= 0 and newline < end:
|
||||
pos = key.end()
|
||||
continue
|
||||
capture_end = end
|
||||
if capture_end > start and body[capture_end - 1] in "\"'":
|
||||
capture_end -= 1
|
||||
yield key.group(0), body[start:capture_end].strip()
|
||||
pos = end
|
||||
|
||||
|
||||
def _parse_gemma_tool_call(tool_name: str, body: str) -> Optional[ToolBlock]:
|
||||
"""Parse a Gemma-style call:tool_name{...} block into a ToolBlock."""
|
||||
tool_name = tool_name.strip().lower().replace("-", "_")
|
||||
@@ -1539,12 +1578,7 @@ def _parse_gemma_tool_call(tool_name: str, body: str) -> Optional[ToolBlock]:
|
||||
if not isinstance(params, dict):
|
||||
params = {}
|
||||
except Exception:
|
||||
# Simple regex key-value extraction fallback
|
||||
params = {}
|
||||
for m in re.finditer(r'(\w+)\s*:\s*["\']?(.*?)["\']?(?=\s*,\s*\w+\s*:|\s*\})', body):
|
||||
k = m.group(1)
|
||||
v = m.group(2).strip()
|
||||
params[k] = v
|
||||
params = dict(_iter_gemma_fallback_items(body))
|
||||
|
||||
from src.tool_schemas import function_call_to_tool_block
|
||||
return function_call_to_tool_block(tool_name, json.dumps(params))
|
||||
|
||||
Reference in New Issue
Block a user