mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-13 14:02:16 +00:00
fix: repair URL authority whitespace before web fetches (#46363)
Port from openclaw/openclaw#91950: normalize LLM-generated URLs like 'https:// docs.example' before web tool safety checks while preserving path and query encoding semantics.
This commit is contained in:
parent
a796e0b796
commit
8fc1cb754b
2 changed files with 32 additions and 0 deletions
|
|
@ -43,6 +43,30 @@ class TestNormalizeUrlForRequest:
|
|||
== "https://xn--mnich-kva.example/K%C3%B6ln"
|
||||
)
|
||||
|
||||
def test_repairs_space_between_scheme_and_authority(self):
|
||||
assert (
|
||||
normalize_url_for_request("https:// docs.openclaw.ai")
|
||||
== "https://docs.openclaw.ai"
|
||||
)
|
||||
|
||||
def test_repairs_tab_between_scheme_and_authority(self):
|
||||
assert (
|
||||
normalize_url_for_request("https:// docs.openclaw.ai/path")
|
||||
== "https://docs.openclaw.ai/path"
|
||||
)
|
||||
|
||||
def test_trims_but_preserves_path_and_query_space_semantics(self):
|
||||
assert (
|
||||
normalize_url_for_request(" https://example.com/a b?q=c d ")
|
||||
== "https://example.com/a%20b?q=c%20d"
|
||||
)
|
||||
|
||||
def test_does_not_collapse_embedded_scheme_separator_in_query(self):
|
||||
assert (
|
||||
normalize_url_for_request("https://example.com/r?next=https:// evil.example")
|
||||
== "https://example.com/r?next=https://%20evil.example"
|
||||
)
|
||||
|
||||
|
||||
class TestIsSafeUrl:
|
||||
def test_public_url_allowed(self):
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import logging
|
|||
import os
|
||||
import socket
|
||||
import asyncio
|
||||
import re
|
||||
from typing import Any, Optional
|
||||
from urllib.parse import parse_qsl, quote, unquote, urljoin, urlparse, urlsplit, urlunsplit
|
||||
|
||||
|
|
@ -52,6 +53,13 @@ def normalize_url_for_request(url: str) -> str:
|
|||
if not raw:
|
||||
return raw
|
||||
|
||||
# Models sometimes emit otherwise valid URLs with whitespace between the
|
||||
# scheme separator and authority (``https:// docs.example``). That position
|
||||
# is never meaningful in HTTP(S) URLs, and repairing it before parsing keeps
|
||||
# web tools from failing on a formatting artifact while leaving path/query
|
||||
# whitespace to the normal percent-encoding path below.
|
||||
raw = re.sub(r"^([A-Za-z][A-Za-z0-9+.-]*://)\s+", r"\1", raw)
|
||||
|
||||
try:
|
||||
parsed = urlsplit(raw)
|
||||
except ValueError:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue