fix: address CodeQL alert and review findings

- config_manager: the "secrets list longer than config list" warning now
  interpolates only config-side data (no key name or secrets-derived
  values), resolving the CodeQL clear-text-logging alert.
- base_plugin: validate_config rejects bool display_duration, matching
  get_display_duration (bool is an int subclass and would otherwise pass
  as a positive number).
- config_helper: merge_configs deep-copies override values in the
  non-recursive branch so mutating the merged result cannot reach back
  into override_config.
- saved_repositories: saves are atomic (temp file + fsync + os.replace),
  so a failed write can no longer truncate saved_repositories.json.
- tests: regression cases for each fix, plus a pin that whole-item
  array secrets (key[] + key[].field both marked) strip to empty {}
  skeletons — no secret values can reach config.json.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NohXi78cwsAKtN1sCfxjUh
This commit is contained in:
Claude
2026-08-07 18:32:26 +00:00
parent c9239d0c46
commit 41f91a40b9
8 changed files with 114 additions and 11 deletions
+3 -2
View File
@@ -172,8 +172,9 @@ class ConfigHelper:
# Recursively merge nested dictionaries
merged[key] = self.merge_configs(merged[key], value)
else:
# Override with new value
merged[key] = value
# Override with new value — deep-copied so mutating the
# merged result can't reach back into override_config.
merged[key] = copy.deepcopy(value)
return merged