clawdi 0.14.50 → 0.14.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
Binary file
|
|
@@ -13,7 +13,7 @@ import re
|
|
|
13
13
|
from datetime import UTC, datetime
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
from typing import Any
|
|
16
|
-
from urllib.parse import parse_qs, urlsplit
|
|
16
|
+
from urllib.parse import parse_qs, quote, urlsplit
|
|
17
17
|
|
|
18
18
|
try: # pragma: no cover - exercised only under mitmdump.
|
|
19
19
|
from mitmproxy import ctx, http
|
|
@@ -408,13 +408,26 @@ def path_matcher_matches(path: str, matcher: dict[str, Any], secrets: dict[str,
|
|
|
408
408
|
secret = secrets.get(str(matcher.get("secretRef", "")))
|
|
409
409
|
if secret is None:
|
|
410
410
|
return False
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
411
|
+
matched = match_secret_path_prefix(path, matcher, secret)
|
|
412
|
+
return matched is not None and (
|
|
413
|
+
matcher_type == "secretRefPrefix" or matched.end() == len(path)
|
|
414
|
+
)
|
|
415
415
|
return False
|
|
416
416
|
|
|
417
417
|
|
|
418
|
+
def match_secret_path_prefix(
|
|
419
|
+
path: str, matcher: dict[str, Any], secret: str
|
|
420
|
+
) -> re.Match[str] | None:
|
|
421
|
+
# Encode only credential characters, never path structure or incoming escapes.
|
|
422
|
+
parts = [re.escape(str(matcher.get("prefix", "")))]
|
|
423
|
+
for char in secret:
|
|
424
|
+
encoded = quote(char, safe="/\\")
|
|
425
|
+
literal = re.escape(char)
|
|
426
|
+
parts.append(literal if encoded == char else f"(?:(?i:{encoded})|{literal})")
|
|
427
|
+
parts.append(re.escape(str(matcher.get("suffix", ""))))
|
|
428
|
+
return re.match("".join(parts), path)
|
|
429
|
+
|
|
430
|
+
|
|
418
431
|
def matcher_matches(value: str | None, matcher: Any, secrets: dict[str, str]) -> bool:
|
|
419
432
|
if not isinstance(matcher, dict):
|
|
420
433
|
return False
|
|
@@ -523,10 +536,12 @@ def apply_path_replace(request_path: str, rewrite: dict[str, Any], secrets: dict
|
|
|
523
536
|
split = urlsplit(request_path or "/")
|
|
524
537
|
prefix = str(replacement.get("prefix", ""))
|
|
525
538
|
suffix = str(replacement.get("suffix", ""))
|
|
526
|
-
|
|
527
|
-
if
|
|
539
|
+
matched = match_secret_path_prefix(split.path, replacement, placeholder)
|
|
540
|
+
if matched is None:
|
|
528
541
|
return request_path
|
|
529
|
-
|
|
542
|
+
# Keep path characters, but encode data that could start a query or fragment.
|
|
543
|
+
actual = quote(actual, safe="/:@!$&'()*+,;=")
|
|
544
|
+
replaced_path = f"{prefix}{actual}{suffix}{split.path[matched.end():]}"
|
|
530
545
|
return f"{replaced_path}?{split.query}" if split.query else replaced_path
|
|
531
546
|
|
|
532
547
|
|
package/package.json
CHANGED