tests(prodtest): remove unsafe YAML parser
What changed, and why it matters
This commit removes a custom YAML loader that was used only in production-test helper code. The custom loader accepted special Python object tags so it could read model config files. It is being replaced with the standard safe YAML loader because an upstream dependency now writes files in a simpler format. The change reduces the risk of accidentally reintroducing unsafe YAML parsing in test tooling, but it is in test code rather than the wallet firmware itself.
Treat this as a hardening/cleanup change in test infrastructure. Verify that the project now pins `ts-tvl` to v2.5 or later so the simpler YAML format is guaranteed, and confirm no other test or tooling files still use `yaml.load` with a non-safe loader. No urgent device-firmware action is indicated.
Security signals we found
Removal of a custom YAML loader that handled python/object/apply tags
Switch from yaml.load with a custom Loader to yaml.safe_load
Commit message explicitly calls the removed parser 'unsafe YAML parser'
Change is in test/production-test helper code, not device firmware
No changelog entry requested
Evidence from the diff
The diff deletes _TropicYamlLoader, a subclass of yaml.SafeLoader that registered a multi-constructor for tag:yaml.org,2002:python/object/apply:. That constructor called construct_sequence/construct_mapping with deep=True and returned the first argument. The code then switched TropicModelState.from_file from yaml.load(..., Loader=_TropicYamlLoader) to yaml.safe_load(...). The commit message says this is safe because ts-tvl v2.5 no longer emits the Python-tagged enum keys. The file is under tests/prodtest_tests/tropic_utils.py, so it is part of the production-test harness, not runtime firmware.
Changed components
tests/prodtest_tests/tropic_utils.pyTropicModelState.from_file methodTropic production-test harnessInspect captured patch +1 / −35
diff --git a/tests/prodtest_tests/tropic_utils.py b/tests/prodtest_tests/tropic_utils.py
index 409548d4..b7322995 100644
--- a/tests/prodtest_tests/tropic_utils.py
+++ b/tests/prodtest_tests/tropic_utils.py
@@ -37,40 +37,6 @@ ROOT = Path(__file__).resolve().parent.parent.parent
DEFAULT_TROPIC_MODEL_CONFIGFILE = ROOT / "tests" / "tropic_model" / "config.yml"
-# TODO: remove once ts-tvl ships the plain-int-key dump from
-# https://github.com/tropicsquare/ts-tvl/pull/14 — then `from_file` can go back
-# to a plain `yaml.safe_load` (and this loader + `_construct_apply` can go).
-class _TropicYamlLoader(yaml.SafeLoader):
- """SafeLoader that tolerates the model's Python-tagged enum keys.
-
- Some commands (e.g. `tropic-lock`) make the model serialize slot indices
- as `!!python/object/apply:tvl.api.l3_api.SlotEnum [N]` instead of a plain
- integer. The stock `SafeLoader` refuses those tags. We map any such
- `apply` node back to its single argument (the integer), so pairing-key
- slots keyed by `SlotEnum(N)` read back identically to the `N` used
- elsewhere. Subclassing keeps this off the global `SafeLoader`.
- """
-
-
-def _construct_apply(
- loader: yaml.SafeLoader, _tag_suffix: str, node: yaml.Node
-) -> t.Any:
- # The SlotEnum form is `apply:...SlotEnum [N]` — a one-element arg sequence.
- if isinstance(node, yaml.SequenceNode):
- args = loader.construct_sequence(node, deep=True)
- elif isinstance(node, yaml.MappingNode):
- # General apply mapping form (`{args: [...], ...}`).
- args = loader.construct_mapping(node, deep=True).get("args", [])
- else:
- args = []
- return args[0] if len(args) == 1 else tuple(args)
-
-
-_TropicYamlLoader.add_multi_constructor(
- "tag:yaml.org,2002:python/object/apply:", _construct_apply
-)
-
-
class TropicModelState:
"""Read-only view over a Tropic model config-output YAML file.
@@ -92,7 +58,7 @@ class TropicModelState:
f"Tropic model output file was not generated: {path}. "
"Did the Tropic model receive SIGINT on shutdown?"
)
- return cls(yaml.load(path.read_text(), Loader=_TropicYamlLoader) or {})
+ return cls(yaml.safe_load(path.read_text()) or {})
@property
def i_config(self) -> dict[str, int]:
Why this scored 33/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.