Files
rclone-jav/bugs-candidates-extension-options.md
T
admin f7fc15b17c Sync working tree before initial Gitea push
Includes:
- cli.py path fix (parents[1]) for config/catalog resolution
- Library cleanup feature design docs (TODO.md, mockup)
- Audit + bug-queue markdowns from May 2026 reliability pass
- .gitignore expanded for transient artifacts
2026-05-26 22:35:42 +02:00

152 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Candidate Findings — Extension Options pages — audit-snapshot-2026-05-24T15-55Z.md
Scope: `src/options/*` (+ `src/shared/*` if referenced)
Required-reading: ext AGENTS.md / mockup / bug-audit-plan.md / project memory
Auditor: fresh Explore agent
---
## Candidate C-1
- **File:** `src/options/options.js:492-525` (SETTINGS_SCHEMA definition)
- **Hunch:** SETTINGS_SCHEMA includes all load/save keys; no asymmetry.
- **Trace:** Lines 191-192 in `load()` read `settings.siteAdapters` and `settings.idNormalizers`, and lines 234-235 in `save()` write them back. SETTINGS_SCHEMA at lines 518, 520 includes both keys. Schema is complete.
- **Question for verifier:** Confirm SETTINGS_SCHEMA includes all keys that load/save cycle uses.
- **Contract refs needed:** none
---
## Candidate C-2
- **File:** `src/options/options-dupe-review.js:561-628` (loadKeepRanking and save)
- **Hunch:** `loadKeepRanking()` runs once at module load (line 628), not when pane is activated. External changes to keep-ranking won't appear until page reload.
- **Trace:** Line 628 calls loadKeepRanking() at module top level. No listener on pane activation (options.js line 37) calls it again. If another tab changes keep-ranking via RPC, this pane won't refresh until reload.
- **Question for verifier:** Should pane activation re-fetch keep-ranking to catch external changes?
- **Contract refs needed:** none
---
## Candidate C-3
- **File:** `src/options/options.js:110-122` (openModal / closeModal)
- **Hunch:** No coordination between modals. Two rapid opens could show two modals simultaneously.
- **Trace:** `openModal(id)` adds "open" class and sets aria-hidden=false. No check if another modal is already open. Multiple modals could be marked "open" at the same time.
- **Question for verifier:** Should only one modal be visible at a time, or is simultaneous open allowed?
- **Contract refs needed:** none
---
## Candidate C-4
- **File:** `src/options/options.js:300` (setNote function)
- **Hunch:** `setNote()` calls `el.innerHTML = html` without sanitization. Assumes caller sanitizes before passing.
- **Trace:** All current callers (lines 308337) build HTML with escapeHtml() before inserting. So current usage is safe. But setNote() is not a safe setter — it's a raw innerHTML setter.
- **Question for verifier:** Is setNote intended as a safe reescaper, or a raw setter expecting pre-sanitized input?
- **Contract refs needed:** none
---
## Candidate C-5
- **File:** `src/options/options.js:533-546` (sanitizeImportedSettings)
- **Hunch:** Array elements are not recursively validated. Example: `siteAdapters: [{ host: 123, selector: [] }]` would pass because the outer type is "array".
- **Trace:** SETTINGS_SCHEMA checks outer type (line 542) but not inner element types. Comment at line 491 says nested objects get recursive validation, but code doesn't implement it for arrays.
- **Question for verifier:** Should imported arrays validate element types, or is current lenient behavior acceptable?
- **Contract refs needed:** none
---
## Candidate C-6
- **File:** `src/options/options.js:210-286` (save function)
- **Hunch:** Save persists to chrome.storage but messages to background.js are fire-and-forget. No confirmation that background applied the settings.
- **Trace:** Line 256 awaits chrome.storage.sync (safe). Lines 261, 278 send messages without waiting for response. If background crashes, settings persist but running extension uses stale config.
- **Question for verifier:** Should save() wait for background.js acknowledgment?
- **Contract refs needed:** none
---
## Candidate C-7
- **File:** `src/options/options-cache.js:113-137` (renderCacheContractBanner)
- **Hunch:** Unrecognized cache_state values silently return empty string instead of showing error.
- **Trace:** Lines 118, 121, 131 test cache_state against known literals. If host sends unexpected state (e.g., `"unknown_state"`), no if matches and line 136 returns "". No error banner shown.
- **Question for verifier:** Should unrecognized cache_state trigger an error banner?
- **Contract refs needed:** none
---
## Candidate C-8
- **File:** `src/options/options.js:386-416` (export/import keep-ranking)
- **Hunch:** Export fails silently if keep-ranking RPC fails. Exported file has empty `_meta.host_config.keep_ranking`. On import, user gets warning but import proceeds anyway. Asymmetric: backup loses data without obvious indication.
- **Trace:** Lines 391-395 try-catch the RPC silently. If it fails, hostConfig.keep_ranking is never set. Export completes anyway (line 405-414). On import, user sees warning at line 560 but can proceed. Keep-ranking is lost in backup/restore cycle.
- **Question for verifier:** Should export fail or warn prominently if keep-ranking cannot be fetched?
- **Contract refs needed:** none
---
## Candidate C-9
- **File:** `src/options/options.js:351-372` (delete-enable-modal flow)
- **Hunch:** If user checks enableDelete and navigates away before confirming modal, box stays unchecked with no way to retry except page reload.
- **Trace:** Line 352-353 check→uncheck→open-modal. If user closes modal without confirming, checkbox is false and no path to re-open the modal exists. Would need page reload or clicking box again.
- **Question for verifier:** Should modal be re-openable from checked state without page reload?
- **Contract refs needed:** none
---
## Candidate C-10
- **File:** `src/options/options-library-issues.js:134-143` (makeReportRow rendering)
- **Hunch:** `entry.path.split("/")` could throw if entry.path is null or not a string.
- **Trace:** Line 134 `fname = entry.filename || entry.path.split("/").pop()`. If entry.filename is falsy and entry.path is null, .split() throws. Entry.path comes from RPC; malformed response could crash render.
- **Question for verifier:** Should there be null/type check for entry.path before .split()?
- **Contract refs needed:** none
---
## Candidate C-11
- **File:** `src/options/options.js:374-382` (input/change listeners)
- **Hunch:** Event listeners call updateSectionSummaries() which reads from DOM. If multiple panes render simultaneously and input fires from hidden pane, stale element reads could occur.
- **Trace:** Lines 374-375 listen for "input" and "change" on panes. Delegated check at line 378 ensures only active pane events fire, but race condition possible if multiple panes render concurrently.
- **Question for verifier:** Is there a render race if load() initializes all panes and events fire before page ready?
- **Contract refs needed:** none
---
## Candidate C-12
- **File:** `src/options/options-library-issues.js:120-131` (makeRow - library issues)
- **Hunch:** The makeRow function for bracket_id and nohyphen_id rows sets data-issue at line 123, which is later checked by _canRenameIdFixRow() line 60. If makeRow is called with malformed entry data, the row might be created but with missing data attributes, making it silently non-renamable.
- **Trace:** Line 120-131 creates row HTML and sets data-issue to entry.issue at line 123. The entry.issue comes from the response. If rendering bracket entries with undefined entry.issue, the row would be created but unclickable (no rename).
- **Question for verifier:** Should missing entry.issue in bracket/nohyphen entries trigger an error, or is silent disable acceptable?
- **Contract refs needed:** none
---
## Summary Stats
- **Total candidates:** 12
- **Severity breakdown:** L (7), M (4), N (1)
- **Areas affected:** stale state (1), modal visibility (1), HTML safety (2), validation (2), error handling (3), RPC failures (1), null safety (1), concurrency (1), missing attributes (1)
---
## VERIFIER NOTES (Phase 1 Moderate verification, stricter prompt + UI-inconvenience rule + storage-quota awareness)
- C-5 (array element validation) — CONFIRMED M. Auditor right; downstream crash in tryAdapters confirmed via content.js read. Promoted as M-1.
- C-6 (save fire-and-forget) — REFUTED. getSettings reads fresh from storage every call; no in-memory cache to invalidate. sendMessage wakes SW per MV3 spec.
- C-8 (export silent fail) — CONFIRMED M, high confidence. Backup→restore cycle silently loses user-typed config. Promoted as M-2.
- C-10 (entry.path crash) — REFUTED. Host's _cache_entry contract guarantees path always non-null string. Unreachable in normal operation.
CHUNK 4 CALIBRATION:
- Severe: 0 (none flagged)
- Moderate rejection: 2/4 = 50% (stop condition >30% triggered)
- Combined: 2/4 = 50%
- Auditor weaknesses: (1) flagging fire-and-forget message patterns without checking if downstream caches, (2) ignoring host-side schema contracts that prevent null/malformed data reaching JS
- L candidates NOT verified per stop condition. Revisit only if needed.