Repository navigation
bugfix: 审计修复与全量测试覆盖 (v1.1.1 后续) - #17
PythonSmall-Q wants to merge 7 commits into
Conversation
- Added a submit button for contest problems in Contests.vue. - Updated problem submission handling to support contest context in Submit.vue. - Introduced a dialog to view standard solutions in ProblemView.vue. - Enhanced mail functionality with target user management in Mail.vue and a new mail-target store. - Implemented cache clearing functionality in Settings.vue. - Added code length display in Status.vue for submission records. - Improved error handling and user feedback in various components. - Updated API services to include new mail and BBS mention read functions. - Added regression tests for various features to ensure stability.
Cut the HUSTOJ /******...****** footer block (extending to EOF) from getsource.php responses so source view, compare and AC export no longer carry the metadata tail. Only a line-initial banner running to EOF is stripped; inline or string-literal occurrences are untouched.
- tests/parser-deep.ts: title cleaning, JUDGE_RESULTS incl. code 3 -> pending, status row matrix, rank AC color palette, countdown order, fetchSource stripping (134 assertions) - tests/api-mapping.ts: createdBy->creator mapping, buildSubmitForm cid/pid priority, parseLanguages (73) - tests/lib-coverage.ts: markdown extensions, discussion permissions, rating colors, format/poller/languages, update check states (110) - tests/ipc-contract.ts: three-end IPC contract consistency across types.ts/main.ts/preload/api.ts (291) - tests/stores.ts: navigation contest context, mail-target, panel, dialog, preferences (108) - bugfix-regressions made CI-safe (live-dump guarded with existsSync skips) - register npm scripts incl. test:offline chain
This comment was marked as resolved.
This comment was marked as resolved.
- navigation: clear activeContest on navigate()/viewProblem() to stop contest context leaking into unrelated submissions - Contests: derive contestPid from problems.indexOf instead of letter math - rank: tighten AC color rule to green-dominant (excludes #ffffff/#ffff00/#00ffff), keep first-blood #aaaaff - judge-api: fetchContestDetail guards a missing contest object - update: treat prerelease versions as older than the same stable; default update dialog focus to 关闭 - Mail: reveal pending thread after loadThreads so scroll target exists - ProblemView: lazy-load standard solution on button click instead of prefetching per problem - tests: strip comments in new suites; loader-stores resolves @/ alias; add regressions for contest clearing, color palette, missing-contest guard, prerelease compare
This comment was marked as resolved.
This comment was marked as resolved.
- ProblemView: actually remove the standard-solution prefetch in load(); openStd now always retries (guard is only stdLoading) and loadStd resets std/stdError before each attempt - sources: tempered banner regex so a mid-file /****** section comment can no longer swallow code up to the real footer banner; add regression for section-comment + footer banner coexistence - rank: explicit parentheses around the AC color condition - parsers: replace lowercase-regex judger heuristic with an explicit judger-name whitelist (saturn/hustoj/jupiter/mars/judge), case-insensitive
This comment was marked as resolved.
This comment was marked as resolved.
- parsers: restore 8-space indentation of the userRating block (edit artifact) - ProblemView: openStd reuses a loaded standard solution and only refetches after a failure or when empty
|
Claude finished @PythonSmall-Q's task in 3m 24s —— View job 本轮复核(针对
|
| 上一轮意见 | 结论 |
|---|---|
electron/parsers.ts:643 缩进被误改为 16 空格 |
✅ 已恢复为 8 空格,与 630–655 行上下文一致 |
ProblemView.openStd() 每次打开都重新请求标程 |
✅ 守卫改为 !stdLoading.value && !std.value && problem.value |
对第二项我按状态机逐条推演过,行为正确:
- 已成功加载后再次打开对话框直接复用
std,不再多发一次 IPC/网络往返; - 切题时
watch(activeProblemId)→load(),其中stdRequest += 1、stdLoading = false、std/stdError置空,因此切题后仍会重新加载; load()递增stdRequest后,在途的loadStd会在finally里因current !== stdRequest跳过,不会把新题目的 loading 态误关;- 加载失败时
std仍为null,下次打开会重新请求(重试路径保留)。
新发现
本轮改动仅两行,未发现回归或阻塞问题。另有 1 条非阻塞 nit 已留 inline(std 为空时对话框没有空态,建议补 v-else 兜底文案)。
仓库规则核对
- 无注释:
443fcd4未新增注释;src/、electron/、tests/全量此前已核对 ✅ - 无
<webview>/window.open/target="_blank"/shell.openExternal:本轮未涉及;全 PR 复核未命中新增调用 ✅ - xmoj.tech 读取走主进程:本轮无渲染进程请求;更新检查等仍走
window.xmoj.app.fetchJsonIPC ✅ CACHE_VERSION:本轮未改变缓存 payload 形状,无需 bump ✅
验证限制
本环境没有 node_modules,npm ci 与 node 执行均需授权且未获通过,因此 npm run typecheck 与 npm run test:offline 仍未实际运行,以上结论均为静态阅读。建议以 CI 结果为准。
结论
上一轮 2 项 nit 均已落实,未发现新缺陷。从我的角度可以合并。
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
|
Claude finished @PythonSmall-Q's task in 8m 12s —— View job 本轮复核(针对
|
| 上一轮意见 | 结论 |
|---|---|
electron/parsers.ts:650 userRating 块缩进 16 空格 |
✅ 已恢复 8 空格 |
ProblemView.openStd() 成功加载后重复请求标程 |
✅ 守卫为 !stdLoading && !std |
std 为空时对话框没有空态 |
✅ 本次提交补上 |
新发现(均非阻塞)
CACHE_VERSION未随 payload 形状变化 bump(建议处理,已留 inline 评论) —— 本 PR 在electron/judge-api.ts的fetchContestList/fetchContestDetail中把条目由createdBy归一化为creator,而contest:list:*/contest:detail:*都在electron/cache.ts的PERSISTED_PREFIXES内、会落盘到page-cache.json。升级用户的旧缓存条目只有createdBy、没有creator,形状与新版产出一致性被破坏。实际不会崩溃(Contests.vue是 cacheOnly → fresh 自愈),但按仓库约定应把CACHE_VERSION从 3 提到 4;顺带还能让旧 parser 缓存的题库标题(problemset:v2:all)与倒计时顺序(home:snapshot)立即失效——ExportAcCode.vue只有fetchAllProblems(true)、没有 fresh 兜底,否则「数字开头标题被截断」的修复对已缓存用户不会马上生效。
Fix this →electron/rank.ts:60style 提取偏窄(nit) ——background(?:-color)?\s*:\s*([^;]+)会把整段声明值(可能含!important、url(...)等附加 token)当成颜色,而isAcceptedRankColor只认纯 6 位 hex /rgb(a);一旦站方输出background-color: #33ff33 !important就会漏标 AC。目前观测到的线上样式不含这些 token,所以不影响现状;若想更稳,可只抓第一个颜色 token:/background(?:-color)?\s*:\s*(#[0-9a-f]{6}|rgba?\([^)]*\))/i。
仓库规则核对
- 无注释:
22edeef未新增注释;对src/、electron/、tests/、scripts/全量新增行再次扫描,0 命中 ✅ - 无
<webview>/window.open/target="_blank"/shell.openExternal:新增行扫描 0 命中 ✅。补充说明:更新提示走的是既有的window.xmoj.app.openLinkIPC,主进程内部对「发布页」类链接会调用shell.openExternal,rich-links/Downloads已在用同一套入口;按字面口径没有新增禁用 API,如维护者口径更严格可再确认这一点 - xmoj.tech 读取走主进程:新增行没有渲染进程
fetch;更新检查仍走window.xmoj.app.fetchJson(主进程 HTTP 客户端)✅ CACHE_VERSION:⚠️ 见上,建议 bump 到 4
验证限制
本环境没有 node_modules,npm ci 与 node --experimental-strip-types …(含 npm run typecheck / npm run test:offline)均被权限拦截、无法执行;以上结论均来自静态阅读,最终请以 CI 结果为准。
结论
最新提交正确收尾了上一轮唯一的 nit,未发现新缺陷。除 CACHE_VERSION 与 rank.ts 颜色提取两处建议外没有阻塞项,从我的角度可以合并。
| return { ok: false, status: result.status, data: null, error: result.error }; | ||
| } | ||
| const list = (result.data.list ?? []).map((contest) => { | ||
| const { createdBy, ...rest } = contest; |
There was a problem hiding this comment.
建议同步 bump CACHE_VERSION(非阻塞)。
本 PR 在 fetchContestList / fetchContestDetail 里把条目的 createdBy 归一化为 creator 并剥离 createdBy。这两类结果由 electron/main.ts 以 contest:list:* / contest:detail:* 写入 PageCache,而这两个前缀都在 electron/cache.ts 的 PERSISTED_PREFIXES 中,会持久化到 page-cache.json:升级用户的旧缓存条目只有 createdBy、没有 creator,与新版产出的 payload 形状不再一致。
实际影响有限:Contests.vue 的 load() / openContest() 都是 cacheOnly → fresh,同一次打开就会被新数据覆盖,不会崩。但按仓库「payload 形状变化要 bump CACHE_VERSION」的约定,建议把它从 3 提升到 4。顺带还能让旧 parser 写入的题库标题(problemset:v2:all)与倒计时顺序(home:snapshot)立即失效——否则 ExportAcCode.vue 只调用 fetchAllProblems(true)、没有 fresh 兜底,旧的「数字开头标题被截断」会继续留在导出文件名里。
@PythonSmall-Q 你这个做的更新检查为什么是 XMOJ Script 的 |

概述
对 xmoj.tech 全页面逐项审计后的修复与接线批次(基于 v1.1.1),共 3 个提交:
🐛 Bug 修复(实跑验证)
parsers.ts标题清洗误删数字开头标题(「24小时降水量」→「小时降水量」)parsers.tsJUDGE_RESULTS 补 code 3(运行并评判),修复评测中自动轮询不启动parsers.tsuserRating 不再误抓判题机名(saturn)与编译参数(-O2)rank.ts排名 AC 颜色按 G 通道判定,修复 #33ff33/#73ff73/#93ff93/#aaffaa 及一血 #aaaaff 全部漏标(OI 榜此前 0/12 正确)parsers.ts倒计时保持网站源顺序(不再按天数重排)sources.ts剥离 getsource.php 尾部 /****** 元信息注释块(源码查看/对比/导出 AC 均受益)🔌 半成品接线(后端早已就绪的部分)
🧪 测试(716 条新断言 + npm run test:offline 一键套件)
验证
npm run typecheck0 错误npm run test:offline全部通过(716+ 断言)备注