From fb4360bbf19a22cbbcc679ad026c5ed3f2080e5e Mon Sep 17 00:00:00 2001
From: 0902young <0902songyang@gmail.com>
Date: Sat, 2 May 2026 14:13:27 +0800
Subject: [PATCH 1/2] Update budget.js
Fixed the XSS cross-site scripting attack vulnerability.
---
budget.js | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/budget.js b/budget.js
index 24651d7..274941c 100644
--- a/budget.js
+++ b/budget.js
@@ -148,15 +148,23 @@ function updateUI() {
}
function showEntry(list, type, title, amount, id) {
- const entry = `
- ${title} : $${amount}
-
-
- `;
- const position = "afterbegin";
- list.insertAdjacentHTML(position, entry);
-}
+ const li = document.createElement("li");
+ li.id = id;
+ li.className = type;
+
+ const entryDiv = document.createElement("div");
+ entryDiv.className = "entry";
+ entryDiv.textContent = `${title} : $${amount}`; // 安全!
+
+ const editDiv = document.createElement("div");
+ editDiv.id = "edit";
+ const deleteDiv = document.createElement("div");
+ deleteDiv.id = "delete";
+
+ li.append(entryDiv, editDiv, deleteDiv);
+ list.insertAdjacentElement("afterbegin", li);
+}
function clearElement(elements) {
elements.forEach((element) => {
element.innerHTML = "";
From f6e093839f4c8b883f1102110de68da66b6913b2 Mon Sep 17 00:00:00 2001
From: 0902young <0902songyang@gmail.com>
Date: Sat, 2 May 2026 14:49:34 +0800
Subject: [PATCH 2/2] Update budget.js
Optimized the budget.js
---
budget.js | 44 ++++++++++++++++++++++++++------------------
1 file changed, 26 insertions(+), 18 deletions(-)
diff --git a/budget.js b/budget.js
index 274941c..b609bfa 100644
--- a/budget.js
+++ b/budget.js
@@ -91,7 +91,7 @@ incomeList.addEventListener("click", deleteOrEdit);
expenseList.addEventListener("click", deleteOrEdit);
allList.addEventListener("click", deleteOrEdit);
-// HELEPER FUNCS
+// HELPER FUNCS
function deleteOrEdit(event) {
const targetBtn = event.target;
const entry = targetBtn.parentNode;
@@ -147,24 +147,28 @@ function updateUI() {
localStorage.setItem("entry_list", JSON.stringify(ENTRY_LIST));
}
-function showEntry(list, type, title, amount, id) {
- const li = document.createElement("li");
- li.id = id;
- li.className = type;
-
- const entryDiv = document.createElement("div");
- entryDiv.className = "entry";
- entryDiv.textContent = `${title} : $${amount}`; // 安全!
-
- const editDiv = document.createElement("div");
- editDiv.id = "edit";
-
- const deleteDiv = document.createElement("div");
- deleteDiv.id = "delete";
+// HELPER FUNC: Escape special HTML characters to prevent XSS attacks
+function escapeHTML(str) {
+ return String(str)
+ .replace(/&/g, "&")
+ .replace(//g, ">")
+ .replace(/"/g, """)
+ .replace(/'/g, "'");
+}
- li.append(entryDiv, editDiv, deleteDiv);
- list.insertAdjacentElement("afterbegin", li);
+function showEntry(list, type, title, amount, id) {
+ const safeTitle = escapeHTML(title);
+ const safeAmount = escapeHTML(amount);
+ const entry = `
+ ${safeTitle} : $${safeAmount}
+
+
+ `;
+ const position = "afterbegin";
+ list.insertAdjacentHTML(position, entry);
}
+
function clearElement(elements) {
elements.forEach((element) => {
element.innerHTML = "";
@@ -184,6 +188,7 @@ function calculateTotal(type, list) {
function calculateBalance(income, outcome) {
return income - outcome;
}
+
function clearInput(inputs) {
inputs.forEach((input) => {
input.value = "";
@@ -203,11 +208,13 @@ function hide(elements) {
function active(element) {
element.classList.add("focus");
}
+
function inactive(elements) {
elements.forEach((element) => {
element.classList.remove("focus");
});
}
+
// ── Exports for testing ──
if (typeof module !== "undefined") {
module.exports = {
@@ -222,7 +229,8 @@ if (typeof module !== "undefined") {
showEntry,
deleteEntry,
editEntry,
+ escapeHTML,
get ENTRY_LIST() { return ENTRY_LIST; },
set ENTRY_LIST(v) { ENTRY_LIST = v; },
};
-}
+}
\ No newline at end of file