From e7d16387dac30868549b37cba70c817f1f4b69e9 Mon Sep 17 00:00:00 2001 From: zefie Date: Thu, 14 Aug 2025 18:57:37 -0400 Subject: [PATCH] prefer wtvshared.escape over encodeURIComponent --- zefie_wtvp_minisrv/app.js | 12 +- zefie_wtvp_minisrv/client_sim.js | 6 +- .../ServiceVault/http_pc/viewergen/index.js | 2 +- .../ServiceVault/wtv-author/clipbook.js | 2 +- .../ServiceVault/wtv-author/congrats.js | 2 +- .../ServiceVault/wtv-author/scrapbook-add.js | 2 +- .../ServiceVault/wtv-author/styles.js | 4 +- .../wtv-disk/content/DownloadScreen.tmpl.js | 2 +- .../ServiceVault/wtv-disk/delete-group.js | 4 +- .../ServiceVault/wtv-disk/get-group-data.js | 2 +- .../includes/ServiceVault/wtv-disk/sync.js | 4 +- .../ServiceVault/wtv-flashrom/get-lc2-page.js | 2 +- .../wtv-flashrom/initiate-lc2-download.js | 6 +- .../ServiceVault/wtv-flashrom/willie.js | 4 +- .../ServiceVault/wtv-mail/readmail.js | 2 +- .../ServiceVault/wtv-mail/sendmail.js | 2 +- .../includes/ServiceVault/wtv-news/news.js | 4 +- .../wtv-passport/messengerlogin.js | 2 +- .../ServiceVault/wtv-proxy/map/catchall.js | 4 +- .../wtv-register/ValidateReviewAccountInfo.js | 4 +- .../ServiceVault/wtv-search/search.js | 4 +- .../includes/ServiceVault/wtv-setup/get.js | 2 +- .../includes/ServiceVault/wtv-setup/set-bg.js | 2 +- .../wtv-tricks/add-to-scrapbook.js | 2 +- .../includes/classes/WTVDisk.js | 2 +- .../includes/classes/WTVGuide.js | 2 +- zefie_wtvp_minisrv/test.js | 342 +++++++++--------- 27 files changed, 223 insertions(+), 205 deletions(-) diff --git a/zefie_wtvp_minisrv/app.js b/zefie_wtvp_minisrv/app.js index 3c2354f9..37998784 100644 --- a/zefie_wtvp_minisrv/app.js +++ b/zefie_wtvp_minisrv/app.js @@ -1028,17 +1028,17 @@ async function processURL(socket, request_headers, pc_services = false) { const qraw_split = qraw[i].split("="); if (qraw_split.length === 2) { const k = qraw_split[0]; - data = decodeURIComponent(qraw[i].split("=")[1].replace(/\+/g, "%20")); + data = wtvshared.unescape(qraw[i].split("=")[1]); if (request_headers.query[k]) { if (typeof request_headers.query[k] === 'string') { const keyarray = [request_headers.query[k]]; request_headers.query[k] = keyarray; } if (wtvshared.isASCII(data)) request_headers.query[k].push(data); - else request_headers.query[k].push(wtvshared.urlDecodeBytes(qraw[i].split("=")[1].replace(/\+/g, "%20"))); + else request_headers.query[k].push(wtvshared.urlDecodeBytes(wtvshared.unescape(qraw[i].split("=")[1]))); } else { if (wtvshared.isASCII(data)) request_headers.query[k] = data; - else request_headers.query[k] = wtvshared.urlDecodeBytes(qraw[i].split("=")[1].replace(/\+/g, "%20")); + else request_headers.query[k] = wtvshared.urlDecodeBytes(wtvshared.unescape(qraw[i].split("=")[1])); } } } @@ -1047,17 +1047,17 @@ async function processURL(socket, request_headers, pc_services = false) { const qraw_split = post_data_string.split("="); if (qraw_split.length === 2) { const k = qraw_split[0]; - data = decodeURIComponent(qraw_split[1].replace(/\+/g, "%20")); + data = wtvshared.unescape(qraw_split[1]); if (request_headers.query[k]) { if (typeof request_headers.query[k] === 'string') { const keyarray = [request_headers.query[k]]; request_headers.query[k] = keyarray; } if (wtvshared.isASCII(data)) request_headers.query[k].push(data); - else request_headers.query[k].push(wtvshared.urlDecodeBytes(qraw_split[1].replace(/\+/g, "%20"))); + else request_headers.query[k].push(wtvshared.urlDecodeBytes(wtvshared.unescape(qraw_split[1]))); } else { if (wtvshared.isASCII(data)) request_headers.query[k] = data; - else request_headers.query[k] = wtvshared.urlDecodeBytes(qraw_split[1].replace(/\+/g, "%20")); + else request_headers.query[k] = wtvshared.urlDecodeBytes(wtvshared.unescape(qraw_split[1])); } } } diff --git a/zefie_wtvp_minisrv/client_sim.js b/zefie_wtvp_minisrv/client_sim.js index a2333a3e..5a5ae50e 100644 --- a/zefie_wtvp_minisrv/client_sim.js +++ b/zefie_wtvp_minisrv/client_sim.js @@ -931,7 +931,7 @@ class WebTVClientSimulator { // Prepare form data as application/x-www-form-urlencoded const formBody = parseResult.formData ? Object.entries(parseResult.formData) - .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value)) + .map(([key, value]) => this.wtvshared.escape(key) + '=' + this.wtvshared.escape(value)) .join('&') : ''; @@ -1210,7 +1210,7 @@ class WebTVClientSimulator { this.debugLog('Using tricks access with POST - first GET the tricks page, then POST to wtv-visit'); // First, GET the tricks page to get the wtv-visit URL - const tricksUrl = `wtv-tricks:/access?url=${encodeURIComponent(this.url)}`; + const tricksUrl = `wtv-tricks:/access?url=${this.wtvshared.escape(this.url)}`; const match = tricksUrl.match(/^([\w-]+):\/?(.*)/); if (match) { const serviceName = match[1]; @@ -1260,7 +1260,7 @@ class WebTVClientSimulator { } else if (this.useTricksAccess && !this.request_type_post) { // Regular tricks access (GET) this.debugLog('Using tricks access for target URL'); - this.url = `wtv-tricks:/access?url=${encodeURIComponent(this.url)}`; + this.url = `wtv-tricks:/access?url=${this.wtvshared.escape(this.url)}`; } // Parse the target URL diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/http_pc/viewergen/index.js b/zefie_wtvp_minisrv/includes/ServiceVault/http_pc/viewergen/index.js index c47bae16..879a3c74 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/http_pc/viewergen/index.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/http_pc/viewergen/index.js @@ -515,7 +515,7 @@ Content-Disposition: attachment; filename="${viewer_file.replace(".exe", ".zip") let update_str = "http://" + request_headers.host + request_headers.request_url.split('?')[0] + "?ssid=" + client_ssid; Object.keys(request_headers.query).forEach((k) => { if (k !== "random_ssid") { - update_str += "&" + encodeURIComponent(k) + "=" + encodeURIComponent(request_headers.query[k]); + update_str += "&" + wtvshared.escape(k) + "=" + wtvshared.escape(request_headers.query[k]); } }); zip.addFile("update_url.txt", update_str); diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/clipbook.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/clipbook.js index ec09529a..f895609e 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/clipbook.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/clipbook.js @@ -1875,7 +1875,7 @@ ${cat.name} if (i % 4 === 0) data += ``; data += ` +href="wtv-author:/add-media-to-block?docName=${docName}&blockNum=${blockNum}&blockClass=23&mediaPath=clipart%2F${wtvshared.escape(cat.path + "/" + cat.images[i])}&thumbnailPath=clipart%2Ficons%2F${wtvshared.escape(cat.path + "/" + cat.images[i])}"> `; } diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/congrats.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/congrats.js index 04a62d2c..95bd83bf 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/congrats.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/congrats.js @@ -109,7 +109,7 @@ Would you like to: -add its address to your mail signature? diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook-add.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook-add.js index 4a4cc92b..b9ffbd6b 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook-add.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook-add.js @@ -39,7 +39,7 @@ if (!request_headers.query.mediaData && !request_headers.query.mediaPath) { 'image': minisrv_config.config.service_logo, 'message': "You are about to add an image to your scrapbook.

Do you wish to continue?", 'buttonlabel1': "Continue", - 'buttonaction1': "wtv-author:/scrapbook-add?confirm=true&mediaPath=" + encodeURIComponent(request_headers.query.mediaPath || ''), + 'buttonaction1': "wtv-author:/scrapbook-add?confirm=true&mediaPath=" + wtvshared.escape(request_headers.query.mediaPath || ''), 'buttonlabel2': "Cancel", 'buttonaction2': "client:donothing" }).getURL(); diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/styles.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/styles.js index 6c3b40dd..522a71b7 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/styles.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/styles.js @@ -118,13 +118,13 @@ vspace=0
+href="wtv-author:/styles?tmplClass=11&docName=${docName}&styleName=${wtvshared.escape(styleName)}&pageNum=${(page > 0) ? (page - 1) : (pages.length - 1)}#minus" id=minus>
${page + 1} of ${pages.length}
+href="wtv-author:/styles?tmplClass=11&docName=${docName}&styleName=${wtvshared.escape(styleName)}&pageNum=${(page+1 < pages.length) ? (page + 1) : 0}#plus" id=plus>
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/content/DownloadScreen.tmpl.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/content/DownloadScreen.tmpl.js index f08cc7b9..506ddb49 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/content/DownloadScreen.tmpl.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/content/DownloadScreen.tmpl.js @@ -45,7 +45,7 @@ if (fail_url === null) fail_url = new clientShowAlert({ let url; if (request_headers.query.url) { - url = encodeURIComponent(request_headers.query.url); + url = wtvshared.escape(request_headers.query.url); } else { url = `wtv-disk:/sync`; if (request_headers.query.diskmap) url += `%3fdiskmap%3d${request_headers.query.diskmap}`; diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/delete-group.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/delete-group.js index 3e8047e3..91941846 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/delete-group.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/delete-group.js @@ -15,7 +15,7 @@ if (request_headers.query.group) { const query = request_headers.query; query['url'] = 'wtv-disk:/delete-group'; const queryString = Object.keys(query) - .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(query[key])) + .map(key => wtvshared.escape(key) + '=' + wtvshared.escape(query[key])) .join('&'); headers = "302 Found\nLocation: wtv-disk:/content/DownloadScreen.tmpl" + (queryString ? ("?" + queryString) : ""); } @@ -47,7 +47,7 @@ if (request_headers.query.group) { state = `invalid`; } const date = client_group_data[group]['last-checkup-time'] || "never"; - data += `${group}${path}${state}${date}\n`; + data += `${group}${path}${state}${date}\n`; }) } data += ` diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/get-group-data.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/get-group-data.js index bb8ea3d8..eea980a4 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/get-group-data.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/get-group-data.js @@ -15,7 +15,7 @@ if (request_headers['wtv-request-type'] === "download") { query['success_url'] = 'wtv-disk:/delete-group'; query['message'] = "Obtaining group data..."; const queryString = Object.keys(query) - .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(query[key])) + .map(key => wtvshared.escape(key) + '=' + wtvshared.escape(query[key])) .join('&'); headers = "302 Found\nwtv-expire-all: wtv-disk:\nLocation: wtv-disk:/content/DownloadScreen.tmpl" + (queryString ? ("?" + queryString) : ""); } \ No newline at end of file diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/sync.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/sync.js index 1645e372..4df1f673 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/sync.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/sync.js @@ -85,7 +85,7 @@ if (request_headers['wtv-request-type'] === 'download') { case "GET": let get_url = service_name + ":/" + update_list[k].location + "?"; if (update_list[k].compress === false) get_url += "dont_compress=true&"; - if (update_list[k].type) get_url += "content_type=" + encodeURIComponent(update_list[k].type) + "&"; + if (update_list[k].type) get_url += "content_type=" + wtvshared.escape(update_list[k].type) + "&"; wtvdl.get(update_list[k].file.replace(diskmap_group_data.base, ""), update_list[k].file, get_url, diskmap_group_name, update_list[k].checksum, update_list[k].uncompressed_size || null, update_list[k].original_filename) break; } @@ -317,7 +317,7 @@ if (request_headers['wtv-request-type'] === 'download') { } } else { const queryString = Object.keys(request_headers.query) - .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(request_headers.query[key])) + .map(key => wtvshared.escape(key) + '=' + wtvshared.escape(request_headers.query[key])) .join('&'); headers = "302 Found\nLocation: wtv-disk:/content/DownloadScreen.tmpl" + (queryString ? ("?" + queryString) : ""); data = ""; diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-lc2-page.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-lc2-page.js index 876c10cd..1c06fea3 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-lc2-page.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-lc2-page.js @@ -42,7 +42,7 @@ async function processLC2DownloadPage(flashrom_info, headers, numparts = null) { } if (!flashrom_info.is_last_part) { - flashrom_info.next_rompath = service_name + ":/get-lc2-page?path=" + encodeURIComponent(flashrom_info.next_rompath.replace(service_name + ":/", "")); + flashrom_info.next_rompath = service_name + ":/get-lc2-page?path=" + wtvshared.escape(flashrom_info.next_rompath.replace(service_name + ":/", "")); } console.log(flashrom_info.next_rompath); diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/initiate-lc2-download.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/initiate-lc2-download.js index a800dca9..c874816f 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/initiate-lc2-download.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/initiate-lc2-download.js @@ -1,11 +1,11 @@ const minisrv_service_file = true; if (request_headers.query.path) { - let url = service_name + ":/get-lc2-page?path=" + encodeURIComponent(request_headers.query.path); + let url = service_name + ":/get-lc2-page?path=" + wtvshared.escape(request_headers.query.path); const romtype = session_data.get("wtv-client-rom-type"); if (romtype === "bf0app") { - url = "client:updateflash?ipaddr=" + minisrv_config.services[service_name].host + "&port=" + minisrv_config.services[service_name].port + "&path=" + encodeURIComponent(service_name + ":/" + request_headers.query.path); - if (request_headers.query.numparts) url += encodeURIComponent("?numparts=" + request_headers.query.numparts); + url = "client:updateflash?ipaddr=" + minisrv_config.services[service_name].host + "&port=" + minisrv_config.services[service_name].port + "&path=" + wtvshared.escape(service_name + ":/" + request_headers.query.path); + if (request_headers.query.numparts) url += wtvshared.escape("?numparts=" + request_headers.query.numparts); } else { if (request_headers.query.numparts) url += "&numparts=" + request_headers.query.numparts; } diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/willie.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/willie.js index eaa1ef77..661ab4da 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/willie.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/willie.js @@ -11,7 +11,7 @@ if (request_headers.query.vflash) delete request_headers.query.vflash; if (request_headers.query.pflash) delete request_headers.query.pflash; for (const [key, value] of Object.entries(request_headers.query)) { - proxy_query += "&" + key + "=" + encodeURIComponent(value); + proxy_query += "&" + key + "=" + wtvshared.escape(value); } if (!minisrv_config.services[service_name].use_zefie_server) { @@ -20,7 +20,7 @@ if (!minisrv_config.services[service_name].use_zefie_server) { const options = { host: "roms.minisrv.dev", - path: "/?minisrv=true&service_name="+encodeURIComponent(service_name)+"&pflash=" + session_data.get("wtv-client-rom-type") + proxy_query, + path: "/?minisrv=true&service_name="+wtvshared.escape(service_name)+"&pflash=" + session_data.get("wtv-client-rom-type") + proxy_query, timeout: 5000, method: 'GET' } diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/readmail.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/readmail.js index f6420671..55b12fd9 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/readmail.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/readmail.js @@ -244,7 +244,7 @@ From: `; if (message.from_name !== message.from_addr) { - data += `${wtvshared.htmlEntitize(message.from_addr)} (${wtvshared.htmlEntitize(message.from_name)})`; + data += `${wtvshared.htmlEntitize(message.from_addr)} (${wtvshared.htmlEntitize(message.from_name)})`; } else { data += `${wtvshared.htmlEntitize(message.from_addr)}`; } diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/sendmail.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/sendmail.js index 5622ac90..263de422 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/sendmail.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/sendmail.js @@ -6,7 +6,7 @@ let message_voicemail_data = null; const intro_seen = session_data.mailstore.checkMailIntroSeen(); if (!intro_seen && !request_headers.query.intro_seen) { // user is trying to bypass the intro screen - headers = "300 OK\nLocation: wtv-mail:/DiplomaMail?came-from=" + encodeURIComponent(request_headers.request_url); + headers = "300 OK\nLocation: wtv-mail:/DiplomaMail?came-from=" + wtvshared.escape(request_headers.request_url); } else if (request_headers.query.clear === "true") { let gourl; if (request_headers.Referer) diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/news.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/news.js index 38c647ff..8122be9f 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/news.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/news.js @@ -592,7 +592,7 @@ ${strftime("%a, %b %e, %Y, %I:%M%P", new Date(Date.parse(response.article.header From: `; if (message.from_name !== message.from_addr) { - data += `${wtvshared.htmlEntitize(message.from_addr)} `; + data += `${wtvshared.htmlEntitize(message.from_addr)} `; } else { data += `${wtvshared.htmlEntitize(response.article.headers.FROM)}`; } @@ -642,7 +642,7 @@ From: if (v.content_type.match(supported_images)) attachment_data += `

`; else if (v.content_type.match(supported_audio)) - attachment_data += ` + attachment_data += `
  ${(v.filename) ? (v.filename) : "Audio file"} (${v.content_type.split('/')[1]} attachment)


`; diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-passport/messengerlogin.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-passport/messengerlogin.js index e9d9e374..38cfc1a6 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-passport/messengerlogin.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-passport/messengerlogin.js @@ -31,7 +31,7 @@ if (messenger_email && messenger_password) { request.end(); const options = { method: 'GET', - headers: { "Authorization": "Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=" + email + ",pwd=" + encodeURIComponent(password) + "," + challenge } + headers: { "Authorization": "Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=" + email + ",pwd=" + wtvshared.escape(password) + "," + challenge } } const request2 = https.get(passporturls, options, (response) => { let req_data = ''; diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-proxy/map/catchall.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-proxy/map/catchall.js index ecd4dedc..7c9033fe 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-proxy/map/catchall.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-proxy/map/catchall.js @@ -54,12 +54,12 @@ lib.get(targetUrl, (res) => { if (urlInputMatch) { pageUrl = urlInputMatch[1]; } - const redirectUrl = `${service_name}:/proxy?id=${proxy_id}&t=${imgExt}&url=${encodeURIComponent(pageUrl)}`; + const redirectUrl = `${service_name}:/proxy?id=${proxy_id}&t=${imgExt}&url=${wtvshared.escape(pageUrl)}`; sendToClient(socket, {'Status': 302, 'Location': redirectUrl}, ''); } else { const idx = data.indexOf('
'); data = data.slice(0, idx); - const redirectUrl = `${service_name}:/proxy?err=${encodeURIComponent(data)}`; + const redirectUrl = `${service_name}:/proxy?err=${wtvshared.escape(data)}`; sendToClient(socket, {'Status': 302, 'Location': redirectUrl}, ''); } }); diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-register/ValidateReviewAccountInfo.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-register/ValidateReviewAccountInfo.js index 57ddac1f..1027a643 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-register/ValidateReviewAccountInfo.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-register/ValidateReviewAccountInfo.js @@ -15,8 +15,8 @@ if (!request_headers.query.registering || data = errpage[1]; } else { if (request_headers.query['Change']) { - let changeUrl = "wtv-register:/ValidateAgreement?registering=" + encodeURIComponent(request_headers.query.registering) + "&subscriber_name=" + encodeURIComponent(request_headers.query.subscriber_name); - changeUrl += "&subscriber_username=" + encodeURIComponent(request_headers.query.subscriber_username) + "&subscriber_contact=" + encodeURIComponent(request_headers.query.subscriber_contact) + "&subscriber_contact_method=" + encodeURIComponent(request_headers.query.subscriber_contact_method); + let changeUrl = "wtv-register:/ValidateAgreement?registering=" + wtvshared.escape(request_headers.query.registering) + "&subscriber_name=" + wtvshared.escape(request_headers.query.subscriber_name); + changeUrl += "&subscriber_username=" + wtvshared.escape(request_headers.query.subscriber_username) + "&subscriber_contact=" + wtvshared.escape(request_headers.query.subscriber_contact) + "&subscriber_contact_method=" + wtvshared.escape(request_headers.query.subscriber_contact_method); const errpage = wtvshared.doRedirect(changeUrl); headers = errpage[0]; data = errpage[1]; diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-search/search.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-search/search.js index 691186e5..7ac8f52c 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-search/search.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-search/search.js @@ -94,9 +94,9 @@ function process(data) { if (result.description) { result.description = result.description.replace(/\/g, '>'); } - result.encodedurl = encodeURIComponent(result.url); + result.encodedurl = wtvshared.escape(result.url); if (result.thumbnail_src) { - result.thumbnail_src = service_name + "/imgproxy?url=" + encodeURIComponent(result.thumbnail_src); + result.thumbnail_src = service_name + "/imgproxy?url=" + wtvshared.escape(result.thumbnail_src); } content.push(result); diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/get.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/get.js index 15ae3870..5703abb9 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/get.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/get.js @@ -46,7 +46,7 @@ Content-Type: text/html`; data = ""; Object.keys(settings_obj).forEach(function (k, v) { - data += k + "=" + encodeURIComponent(settings_obj[k]) + "&"; + data += k + "=" + wtvshared.escape(settings_obj[k]) + "&"; }); data = data.slice(0, (data.length - 1)); diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/set-bg.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/set-bg.js index 3d869494..6520c669 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/set-bg.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/set-bg.js @@ -110,7 +110,7 @@ Choose the songs that you'd like to include. let songTitle = musicList[k]['title']; if (songTitle.length > strLenLimit) songTitle = musicList[k]['title'].slice(0, strLenLimit - 3) + "..."; if (musicList.length > 14) data += ''; - data += `${songTitle} + data += `${songTitle} `; if (musicList.length > 14) data += ''; songsListed++; diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/add-to-scrapbook.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/add-to-scrapbook.js index f631300b..427ec30c 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/add-to-scrapbook.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/add-to-scrapbook.js @@ -11,6 +11,6 @@ if (!request_headers.query.url && !request_headers.query.mediaPath) { handleError('No URL provided'); } else { const mediaURL = request_headers.query.url || request_headers.query.mediaPath; - const targetURL = 'wtv-author:/scrapbook-add?mediaPath=' + encodeURIComponent(mediaURL); + const targetURL = 'wtv-author:/scrapbook-add?mediaPath=' + wtvshared.escape(mediaURL); sendToClient(socket, {'Status': 302, 'Location': targetURL, 'wtv-visit': targetURL}, ''); } \ No newline at end of file diff --git a/zefie_wtvp_minisrv/includes/classes/WTVDisk.js b/zefie_wtvp_minisrv/includes/classes/WTVDisk.js index d2094604..4fe115ad 100644 --- a/zefie_wtvp_minisrv/includes/classes/WTVDisk.js +++ b/zefie_wtvp_minisrv/includes/classes/WTVDisk.js @@ -126,7 +126,7 @@ class WTVDownloadList { * @param {string} destination Destination file path in the User Store */ putUserStoreDest(path, destination) { - this.put(path, `${this.service_name}:/userstore?partialPath=${encodeURIComponent(destination)}`); + this.put(path, `${this.service_name}:/userstore?partialPath=${this.wtvshared.escape(destination)}`); } /** diff --git a/zefie_wtvp_minisrv/includes/classes/WTVGuide.js b/zefie_wtvp_minisrv/includes/classes/WTVGuide.js index 7cf5bd9f..be8d4796 100644 --- a/zefie_wtvp_minisrv/includes/classes/WTVGuide.js +++ b/zefie_wtvp_minisrv/includes/classes/WTVGuide.js @@ -92,7 +92,7 @@ class WTVGuide { if (!link_word_start_letter && link_word_for_link.length > 0) link_word_start_letter = link_word_for_link.charAt(0).toUpperCase(); if (!link_word_override) link_word_override = link_word; - const link_url = `wtv-guide:/help?topic=Glossary&subtopic=${link_word_start_letter}&page=${link_word_for_link}&word=${encodeURIComponent(link_word_override)}` + const link_url = `wtv-guide:/help?topic=Glossary&subtopic=${link_word_start_letter}&page=${link_word_for_link}&word=${this.wtvshared.escape(link_word_override)}` const new_definition = definition.slice(0, original_start - search.length) + `${link_word}` + definition.slice(end + 7); definition = new_definition; } diff --git a/zefie_wtvp_minisrv/test.js b/zefie_wtvp_minisrv/test.js index fa2487df..62759333 100644 --- a/zefie_wtvp_minisrv/test.js +++ b/zefie_wtvp_minisrv/test.js @@ -28,6 +28,7 @@ function checkScopeErrors(file) { // Check if file is in ServiceDeps or ServiceVault directories const normalizedFile = file.replace(/\\/g, '/'); const isServiceFile = normalizedFile.includes('includes/ServiceDeps') || normalizedFile.includes('includes/ServiceVault'); + const isWTVSharedFile = normalizedFile.includes('includes/classes/WTVShared.js'); const eslintConfig = { "parserOptions": { @@ -59,170 +60,187 @@ function checkScopeErrors(file) { "message": "unescape() is deprecated. Use decodeURIComponent() instead." } ], - "no-restricted-syntax": [ - "warn", - // String methods - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.property.name='substr']", - "message": "String.prototype.substr() is deprecated. Use String.prototype.slice() instead." - }, - { - "selector": "CallExpression[callee.name='substr']", - "message": "substr() is deprecated. Use slice() instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.property.name='substring']", - "message": "substring() found, for continuity, please use String.prototype.slice() instead." - }, - { - "selector": "CallExpression[callee.name='substring']", - "message": "substring() found, for continuity, please use slice() instead." - }, - // Buffer methods - { - "selector": "CallExpression[callee.type='Buffer'][callee.property.name='slice']", - "message": "Found .slice() call. If this is on a Buffer, use Buffer.subarray() instead for better performance." - }, - { - "selector": "NewExpression[callee.name='Buffer']", - "message": "new Buffer() is deprecated. Use Buffer.from(), Buffer.alloc(), or Buffer.allocUnsafe() instead." - }, - // Node.js specific deprecations - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='fs'][callee.property.name='exists']", - "message": "fs.exists() is deprecated. Use fs.existsSync() or fs.access() instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isArray']", - "message": "util.isArray() is deprecated. Use Array.isArray() instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isBoolean']", - "message": "util.isBoolean() is deprecated. Use typeof x === 'boolean' instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isBuffer']", - "message": "util.isBuffer() is deprecated. Use Buffer.isBuffer() instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isDate']", - "message": "util.isDate() is deprecated. Use x instanceof Date instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isError']", - "message": "util.isError() is deprecated. Use x instanceof Error instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isFunction']", - "message": "util.isFunction() is deprecated. Use typeof x === 'function' instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isNull']", - "message": "util.isNull() is deprecated. Use x === null instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isNullOrUndefined']", - "message": "util.isNullOrUndefined() is deprecated. Use x == null instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isNumber']", - "message": "util.isNumber() is deprecated. Use typeof x === 'number' instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isObject']", - "message": "util.isObject() is deprecated. Use typeof x === 'object' && x !== null instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isPrimitive']", - "message": "util.isPrimitive() is deprecated. Use manual type checking instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isRegExp']", - "message": "util.isRegExp() is deprecated. Use x instanceof RegExp instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isString']", - "message": "util.isString() is deprecated. Use typeof x === 'string' instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isSymbol']", - "message": "util.isSymbol() is deprecated. Use typeof x === 'symbol' instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isUndefined']", - "message": "util.isUndefined() is deprecated. Use x === undefined instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='debug']", - "message": "util.debug() is deprecated. Use console.error() instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='error']", - "message": "util.error() is deprecated. Use console.error() instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='print']", - "message": "util.print() is deprecated. Use console.log() instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='puts']", - "message": "util.puts() is deprecated. Use console.log() instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='pump']", - "message": "util.pump() is deprecated. Use stream.pipeline() instead." - }, - // Domain module (deprecated) - { - "selector": "CallExpression[callee.name='require'][arguments.0.value='domain']", - "message": "The 'domain' module is deprecated. Use AsyncLocalStorage or async_hooks instead." - }, - // Crypto deprecations - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='crypto'][callee.property.name='createCredentials']", - "message": "crypto.createCredentials() is deprecated. Use tls.createSecureContext() instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='crypto'][callee.property.name='Credentials']", - "message": "crypto.Credentials is deprecated. Use tls.SecureContext instead." - }, - // Custom project-specific deprecations - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='session_data'][callee.property.name='hasCap']", - "message": "session_data.hasCap() is deprecated. Use session_data.capabilities.get() instead." - }, - { - "selector": "CallExpression[callee.type='MemberExpression'][callee.object.type='MemberExpression'][callee.object.property.name='session_data'][callee.property.name='hasCap']", - "message": "session_data.hasCap() is deprecated. Use session_data.capabilities.get() instead." - }, - // Type coercion warnings - { - "selector": "BinaryExpression[operator='==='][left.type='Literal'][left.value=/^\\d+$/][left.typeof='number'][right.type='Identifier']", - "message": "Comparing string literal that looks like a number with a variable using strict equality. Consider parseInt() or ensure both operands are the same type." - }, - { - "selector": "BinaryExpression[operator='==='][left.type='Identifier'][right.type='Literal'][right.value=/^\\d+$/][right.typeof='number']", - "message": "Comparing variable with string literal that looks like a number using strict equality. Consider parseInt() or ensure both operands are the same type." - }, - { - "selector": "BinaryExpression[operator='==='][left.type='Literal'][left.typeof='string'][right.type='Literal'][right.typeof='number']", - "message": "Comparing string literal with number literal using strict equality. This will always be false." - }, - { - "selector": "BinaryExpression[operator='==='][left.type='Literal'][left.typeof='number'][right.type='Literal'][right.typeof='string']", - "message": "Comparing number literal with string literal using strict equality. This will always be false." - }, - { - "selector": "BinaryExpression[operator='!=='][left.type='Literal'][left.typeof='string'][right.type='Literal'][right.typeof='number']", - "message": "Comparing string literal with number literal using strict inequality. This will always be true." - }, - { - "selector": "BinaryExpression[operator='!=='][left.type='Literal'][left.typeof='number'][right.type='Literal'][right.typeof='string']", - "message": "Comparing number literal with string literal using strict inequality. This will always be true." - } - ] + "no-restricted-syntax": [] } }; + + // Build restricted syntax rules array + const restrictedSyntaxRules = [ + "warn", + // String methods + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.property.name='substr']", + "message": "String.prototype.substr() is deprecated. Use String.prototype.slice() instead." + }, + { + "selector": "CallExpression[callee.name='substr']", + "message": "substr() is deprecated. Use slice() instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.property.name='substring']", + "message": "substring() found, for continuity, please use String.prototype.slice() instead." + }, + { + "selector": "CallExpression[callee.name='substring']", + "message": "substring() found, for continuity, please use slice() instead." + }, + // Buffer methods + { + "selector": "CallExpression[callee.type='Buffer'][callee.property.name='slice']", + "message": "Found .slice() call. If this is on a Buffer, use Buffer.subarray() instead for better performance." + }, + { + "selector": "NewExpression[callee.name='Buffer']", + "message": "new Buffer() is deprecated. Use Buffer.from(), Buffer.alloc(), or Buffer.allocUnsafe() instead." + }, + // Node.js specific deprecations + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='fs'][callee.property.name='exists']", + "message": "fs.exists() is deprecated. Use fs.existsSync() or fs.access() instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isArray']", + "message": "util.isArray() is deprecated. Use Array.isArray() instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isBoolean']", + "message": "util.isBoolean() is deprecated. Use typeof x === 'boolean' instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isBuffer']", + "message": "util.isBuffer() is deprecated. Use Buffer.isBuffer() instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isDate']", + "message": "util.isDate() is deprecated. Use x instanceof Date instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isError']", + "message": "util.isError() is deprecated. Use x instanceof Error instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isFunction']", + "message": "util.isFunction() is deprecated. Use typeof x === 'function' instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isNull']", + "message": "util.isNull() is deprecated. Use x === null instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isNullOrUndefined']", + "message": "util.isNullOrUndefined() is deprecated. Use x == null instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isNumber']", + "message": "util.isNumber() is deprecated. Use typeof x === 'number' instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isObject']", + "message": "util.isObject() is deprecated. Use typeof x === 'object' && x !== null instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isPrimitive']", + "message": "util.isPrimitive() is deprecated. Use manual type checking instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isRegExp']", + "message": "util.isRegExp() is deprecated. Use x instanceof RegExp instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isString']", + "message": "util.isString() is deprecated. Use typeof x === 'string' instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isSymbol']", + "message": "util.isSymbol() is deprecated. Use typeof x === 'symbol' instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='isUndefined']", + "message": "util.isUndefined() is deprecated. Use x === undefined instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='debug']", + "message": "util.debug() is deprecated. Use console.error() instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='error']", + "message": "util.error() is deprecated. Use console.error() instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='print']", + "message": "util.print() is deprecated. Use console.log() instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='puts']", + "message": "util.puts() is deprecated. Use console.log() instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='util'][callee.property.name='pump']", + "message": "util.pump() is deprecated. Use stream.pipeline() instead." + }, + // Domain module (deprecated) + { + "selector": "CallExpression[callee.name='require'][arguments.0.value='domain']", + "message": "The 'domain' module is deprecated. Use AsyncLocalStorage or async_hooks instead." + }, + // Crypto deprecations + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='crypto'][callee.property.name='createCredentials']", + "message": "crypto.createCredentials() is deprecated. Use tls.createSecureContext() instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='crypto'][callee.property.name='Credentials']", + "message": "crypto.Credentials is deprecated. Use tls.SecureContext instead." + }, + // Custom project-specific deprecations + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.name='session_data'][callee.property.name='hasCap']", + "message": "session_data.hasCap() is deprecated. Use session_data.capabilities.get() instead." + }, + { + "selector": "CallExpression[callee.type='MemberExpression'][callee.object.type='MemberExpression'][callee.object.property.name='session_data'][callee.property.name='hasCap']", + "message": "session_data.hasCap() is deprecated. Use session_data.capabilities.get() instead." + } + ]; + + // Add encodeURIComponent warning only if this is not WTVShared.js + if (!isWTVSharedFile) { + restrictedSyntaxRules.push({ + "selector": "CallExpression[callee.name='encodeURIComponent']", + "message": "Use wtvshared.escape() instead of encodeURIComponent() for consistency." + }); + } + + // Add type coercion warnings + restrictedSyntaxRules.push( + { + "selector": "BinaryExpression[operator='==='][left.type='Literal'][left.value=/^\\d+$/][left.typeof='number'][right.type='Identifier']", + "message": "Comparing string literal that looks like a number with a variable using strict equality. Consider parseInt() or ensure both operands are the same type." + }, + { + "selector": "BinaryExpression[operator='==='][left.type='Identifier'][right.type='Literal'][right.value=/^\\d+$/][right.typeof='number']", + "message": "Comparing variable with string literal that looks like a number using strict equality. Consider parseInt() or ensure both operands are the same type." + }, + { + "selector": "BinaryExpression[operator='==='][left.type='Literal'][left.typeof='string'][right.type='Literal'][right.typeof='number']", + "message": "Comparing string literal with number literal using strict equality. This will always be false." + }, + { + "selector": "BinaryExpression[operator='==='][left.type='Literal'][left.typeof='number'][right.type='Literal'][right.typeof='string']", + "message": "Comparing number literal with string literal using strict equality. This will always be false." + }, + { + "selector": "BinaryExpression[operator='!=='][left.type='Literal'][left.typeof='string'][right.type='Literal'][right.typeof='number']", + "message": "Comparing string literal with number literal using strict inequality. This will always be true." + }, + { + "selector": "BinaryExpression[operator='!=='][left.type='Literal'][left.typeof='number'][right.type='Literal'][right.typeof='string']", + "message": "Comparing number literal with string literal using strict inequality. This will always be true." + } + ); + + // Set the rules array + eslintConfig.rules["no-restricted-syntax"] = restrictedSyntaxRules; // Add global variables for service files to ignore specific undefined variables if (isServiceFile) {