Fix five quality findings from adversarial code review
sitecustomize.py — _install():
- Scope hook to middlewared service process only via sys.argv[0] check;
previously any tool in the same venv (midclt, debug scripts) would also
get its imports of the two target modules intercepted.
- Exec-chain a displaced sitecustomize.py: if apply.sh backed up a
pre-existing sitecustomize.py to .pre-truecloud-patch, run it in a
sandboxed namespace before installing our hook so any startup code
(path additions, codec registrations) still takes effect.
sitecustomize.py — _b2_restic_config():
- Validate expected credential fields ("account", "key") before accessing
them; raise a named KeyError listing what is missing and what is present
so a schema change produces an attributable error at backup time rather
than a bare KeyError with no indication this patch is involved.
sitecustomize.py — get_restic_config wrapper:
- Extend URL fix to cover all three flag forms restic accepts:
-r <url> (existing)
--repo <url> (long two-element form, now checked)
--repo=<url> (long single-element form, now handled)
Without this, a restic CLI change from -r to --repo would silently make
the fix a no-op while verify still reported the patch as OK.
patch_ui.py — find_bundle():
- Remove UnicodeDecodeError from except clause; errors="replace" in the
open() call means the exception can never be raised, and its presence
suggested the error parameter was not understood.
This commit is contained in:
+1
-1
@@ -61,7 +61,7 @@ def find_bundle():
|
||||
content = fh.read()
|
||||
if FIND.search(content):
|
||||
matches.append((path, content))
|
||||
except (UnicodeDecodeError, PermissionError, OSError):
|
||||
except OSError:
|
||||
continue
|
||||
|
||||
if not matches:
|
||||
|
||||
+47
-5
@@ -131,6 +131,12 @@ def _patch_b2(module):
|
||||
|
||||
def _b2_restic_config(task):
|
||||
p = task["credentials"]["provider"]
|
||||
missing = [f for f in ("account", "key") if f not in p]
|
||||
if missing:
|
||||
raise KeyError(
|
||||
f"truecloud-patch: B2 provider missing field(s) {missing!r}; "
|
||||
f"schema may have changed. Present: {sorted(p)!r}"
|
||||
)
|
||||
return "", {"B2_ACCOUNT_ID": p["account"], "B2_ACCOUNT_KEY": p["key"]}
|
||||
|
||||
cls.get_restic_config = staticmethod(_b2_restic_config)
|
||||
@@ -154,12 +160,26 @@ def _patch_restic(module):
|
||||
# env construction, and everything else we don't own.
|
||||
result = _orig(cloud_backup)
|
||||
|
||||
# Scan the built command for the -r <repo> argument and fix the URL if
|
||||
# it has a stray leading slash: "b2:/bucket/path" → "b2:bucket/path".
|
||||
# Scan the built command for the repo argument and fix the URL if it
|
||||
# has a stray leading slash: "b2:/bucket/path" → "b2:bucket/path".
|
||||
# "scheme://path" is intentional (Storj) and must not be touched.
|
||||
# Covers all three flag forms restic accepts:
|
||||
# -r <url> (short, two-element)
|
||||
# --repo <url> (long, two-element)
|
||||
# --repo=<url> (long, single-element)
|
||||
cmd = list(result.cmd)
|
||||
for i, part in enumerate(cmd):
|
||||
if i and cmd[i - 1] == "-r":
|
||||
if part.startswith("--repo="):
|
||||
url = part[len("--repo="):]
|
||||
scheme, sep, rest = url.partition(":")
|
||||
if sep and rest.startswith("/") and not rest.startswith("//"):
|
||||
cmd[i] = f"--repo={scheme}:{rest[1:]}"
|
||||
try:
|
||||
return dataclasses.replace(result, cmd=cmd)
|
||||
except TypeError:
|
||||
return result._replace(cmd=cmd)
|
||||
break
|
||||
if i and cmd[i - 1] in ("-r", "--repo"):
|
||||
scheme, sep, rest = part.partition(":")
|
||||
if sep and rest.startswith("/") and not rest.startswith("//"):
|
||||
cmd[i] = f"{scheme}:{rest[1:]}"
|
||||
@@ -209,10 +229,32 @@ def _record_status(fullname: str, ok: bool, detail: str = "") -> None:
|
||||
def _install():
|
||||
import os
|
||||
if os.path.exists("/data/truecloud-patch/disabled"):
|
||||
return # kill switch: touch /data/truecloud-patch/disabled to bypass this hook
|
||||
return # kill switch
|
||||
# Scope to the middlewared service process only — not midclt, debug scripts,
|
||||
# or other tools that happen to share the same venv.
|
||||
_argv0 = (sys.argv or [""])[0]
|
||||
if os.path.basename(_argv0) != "middlewared":
|
||||
return
|
||||
import importlib.util
|
||||
if importlib.util.find_spec("middlewared") is None:
|
||||
return # not a middlewared Python process; nothing to do
|
||||
return
|
||||
# If apply.sh displaced an existing sitecustomize.py, exec it first so any
|
||||
# iX-provided startup code (path additions, codec registrations, etc.) still
|
||||
# runs. We use a separate namespace so it cannot shadow our globals.
|
||||
_self = globals().get("__file__", "")
|
||||
if _self:
|
||||
_pre = _self + ".pre-truecloud-patch"
|
||||
if os.path.isfile(_pre):
|
||||
try:
|
||||
import builtins
|
||||
with open(_pre, encoding="utf-8") as _fh:
|
||||
exec( # noqa: S102
|
||||
compile(_fh.read(), _pre, "exec"),
|
||||
{"__builtins__": builtins, "__file__": _pre,
|
||||
"__name__": "sitecustomize"},
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
sys.meta_path.append(_Finder())
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user