Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
162d588
Merge pull request #772 from XMOJ-Script-dev/dev
boomzero Feb 8, 2025
d724438
Merge pull request #781 from XMOJ-Script-dev/dev
boomzero Feb 21, 2025
8b4a2c1
Merge pull request #786 from XMOJ-Script-dev/dev
boomzero Feb 23, 2025
e40b292
Merge pull request #800 from XMOJ-Script-dev/dev
boomzero May 4, 2025
c8ed5aa
Merge pull request #804 from XMOJ-Script-dev/dev
boomzero Jun 4, 2025
e4f659f
Merge pull request #813 from XMOJ-Script-dev/dev
boomzero Jun 22, 2025
d24fe86
Merge pull request #819 from XMOJ-Script-dev/dev
boomzero Jul 10, 2025
1a75572
Merge pull request #823 from XMOJ-Script-dev/dev
boomzero Jul 25, 2025
b789bf2
Update Update.json
boomzero Jul 25, 2025
13058b6
Merge pull request #827 from XMOJ-Script-dev/dev
boomzero Aug 9, 2025
c22fd31
Merge pull request #836 from XMOJ-Script-dev/dev
boomzero Aug 22, 2025
6adac8d
Parse release notes from comment block
boomzero Aug 24, 2025
f86a45e
Update bug.yml
boomzero Aug 24, 2025
84474cc
Merge pull request #854 from XMOJ-Script-dev/dev
boomzero Sep 14, 2025
7950ae8
Merge pull request #857 from XMOJ-Script-dev/dev
boomzero Sep 27, 2025
dfe8cf8
Merge pull request #874 from XMOJ-Script-dev/dev
boomzero Oct 4, 2025
54d39cf
Update GitHub Actions workflow to skip bot triggers
PythonSmall-Q Feb 7, 2026
462621a
Merge pull request #891 from XMOJ-Script-dev/dev
PythonSmall-Q Feb 7, 2026
27863a7
Prevent UpdateVersion from running if last commit was by github-actio…
boomzero Feb 11, 2026
280bc24
Merge branch 'master' of github.com:XMOJ-Script-dev/XMOJ-Script
boomzero Feb 11, 2026
4a671fc
Merge pull request #908 from XMOJ-Script-dev/dev
boomzero Feb 16, 2026
e3bbe9e
Merge pull request #912 from XMOJ-Script-dev/dev
boomzero Feb 19, 2026
fab6593
Allow metadata updates on edited PRs after bot version commit
boomzero Feb 23, 2026
2f7e9d6
Allow metadata updates on edited PRs after bot version commit
boomzero Feb 23, 2026
e14e33c
Merge pull request #921 from XMOJ-Script-dev/dev
boomzero Feb 27, 2026
a5182a6
Fix Problem Switcher Not Update
def-WA2025 Mar 12, 2026
f908046
3.3.1
github-actions[bot] Mar 12, 2026
9ae2c90
Update version info to 3.3.1
github-actions[bot] Mar 12, 2026
18fded0
Change version from 3.3.1 to 3.4.0
def-WA2025 Mar 12, 2026
226b059
Bump version from 3.3.1 to 3.4.0
def-WA2025 Mar 12, 2026
c30762b
Update version from 1.999990.0 to 1.10.0
def-WA2025 Mar 12, 2026
63af153
Bump version from 3.3.1 to 3.4.0
def-WA2025 Mar 12, 2026
df63a95
Fix Problem Switcher Not Update
def-WA2025 Mar 12, 2026
4b00024
Fix Problem Switcher Not Update
def-WA2025 Mar 12, 2026
cb97653
Fix Problem Switcher Not Update
def-WA2025 Mar 12, 2026
9e6161a
Merge branch 'dev' into fix-problem-switcher-not-update
def-WA2025 Mar 12, 2026
9c5a57d
Update time and description of 3.4.0
github-actions[bot] Mar 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Update.json
Original file line number Diff line number Diff line change
Expand Up @@ -3423,16 +3423,16 @@
],
"Notes": "<b>Bug 修复</b><br>\n- 修复了暗色模式下比赛排名表(contestrank-oi.php 和 contestrank-correct.php)颜色显示异常的问题(#916)<br>\n- 修复了 WebSocket 弹窗通知未遵循各功能独立弹窗开关(BBSPopup/MessagePopup)的问题(#919)"
},
"3.3.1": {
"UpdateDate": 1772981411290,
"3.4.0": {
"UpdateDate": 1773332303425,
"Prerelease": true,
"UpdateContents": [
{
"PR": 924,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Emm, ?

"Description": "Add ImageEnlarger feature with modal viewer"
"PR": 931,
"Description": "Fix problem switcher not update"
}
],
"Notes": "No release notes were provided for this release."
"Notes": "Fix ProblemSwitcher Not Update"
}
}
}
46 changes: 28 additions & 18 deletions XMOJ.user.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ==UserScript==
// @name XMOJ
// @version 3.3.1
// @version 3.4.0
// @description XMOJ增强脚本
// @author @XMOJ-Script-dev, @langningchen and the community
// @namespace https://github/langningchen
Expand Down Expand Up @@ -533,6 +533,29 @@ let RequestAPI = (Action, Data, CallBack) => {
}
};

unsafeWindow.GetContestProblemList = async function(RefreshList) {
try {
const contestReq = await fetch("https://www.xmoj.tech/contest.php?cid=" + SearchParams.get("cid"));
const res = await contestReq.text();
if (contestReq.status === 200 && res.indexOf("比赛尚未开始或私有,不能查看题目。") === -1) {
const parser = new DOMParser();
const dom = parser.parseFromString(res, "text/html");
const rows = (dom.querySelector("#problemset > tbody")).rows;
let problemList = [];
for (let i = 0; i < rows.length; i++) {
problemList.push({
"title": rows[i].children[2].innerText,
"url": rows[i].children[2].children[0].href
});
}
localStorage.setItem("UserScript-Contest-" + SearchParams.get("cid") + "-ProblemList", JSON.stringify(problemList));
if (RefreshList) location.reload();
}
} catch (e) {
console.error(e);
}
}

// WebSocket Notification System
let NotificationSocket = null;
let NotificationSocketReconnectAttempts = 0;
Expand Down Expand Up @@ -2272,22 +2295,8 @@ async function main() {
}
let ContestProblemList = localStorage.getItem("UserScript-Contest-" + SearchParams.get("cid") + "-ProblemList");
if (ContestProblemList == null) {
const contestReq = await fetch("https://www.xmoj.tech/contest.php?cid=" + SearchParams.get("cid"));
const res = await contestReq.text();
if (contestReq.status === 200 && res.indexOf("比赛尚未开始或私有,不能查看题目。") === -1) {
const parser = new DOMParser();
const dom = parser.parseFromString(res, "text/html");
const rows = (dom.querySelector("#problemset > tbody")).rows;
let problemList = [];
for (let i = 0; i < rows.length; i++) {
problemList.push({
"title": rows[i].children[2].innerText,
"url": rows[i].children[2].children[0].href
});
}
localStorage.setItem("UserScript-Contest-" + SearchParams.get("cid") + "-ProblemList", JSON.stringify(problemList));
ContestProblemList = JSON.stringify(problemList);
}
unsafeWindow.GetContestProblemList(false);
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Await the async GetContestProblemList call before reading from localStorage, otherwise the list can still be null and JSON.parse will throw.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At XMOJ.user.js, line 2296:

<comment>Await the async `GetContestProblemList` call before reading from localStorage, otherwise the list can still be null and `JSON.parse` will throw.</comment>

<file context>
@@ -2270,22 +2293,8 @@ async function main() {
-                                localStorage.setItem("UserScript-Contest-" + SearchParams.get("cid") + "-ProblemList", JSON.stringify(problemList));
-                                ContestProblemList = JSON.stringify(problemList);
-                            }
+                            unsafeWindow.GetContestProblemList(false);
+                            ContestProblemList = localStorage.getItem("UserScript-Contest-" + SearchParams.get("cid") + "-ProblemList");
                         }
</file context>
Suggested change
unsafeWindow.GetContestProblemList(false);
await unsafeWindow.GetContestProblemList(false);
Fix with Cubic

ContestProblemList = localStorage.getItem("UserScript-Contest-" + SearchParams.get("cid") + "-ProblemList");
}

let problemSwitcher = document.createElement("div");
Expand All @@ -2310,6 +2319,7 @@ async function main() {
problemSwitcher.style.flexDirection = "column";

let problemList = JSON.parse(ContestProblemList);
problemSwitcher.innerHTML += `<a href="javascript:void(0)" onclick="GetContestProblemList(true)" title="刷新列表" class="mb-2" style="text-align: center;" active>刷新</a>`;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (javascript.browser.security.insecure-document-method): User controlled data in methods like innerHTML, outerHTML or document.write is an anti-pattern that can lead to XSS vulnerabilities

Source: opengrep

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (javascript.browser.security.insecure-innerhtml): User controlled data in a problemSwitcher.innerHTML is an anti-pattern that can lead to XSS vulnerabilities

Source: opengrep

for (let i = 0; i < problemList.length; i++) {
let buttonText = "";
if (i < 26) {
Expand Down Expand Up @@ -6069,4 +6079,4 @@ int main()

main().then(r => {
console.log("XMOJ-Script loaded successfully!");
});
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "xmoj-script",
"version": "3.3.1",
"version": "3.4.0",
"description": "an improvement script for xmoj.tech",
"main": "AddonScript.js",
"scripts": {
Expand Down