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