aboutsummaryrefslogtreecommitdiff
path: root/webAO/client
diff options
context:
space:
mode:
authorOsmium Sorcerer <os@sof.beauty>2026-06-03 11:23:33 +0000
committerOsmium Sorcerer <os@sof.beauty>2026-06-06 03:09:27 +0000
commitfd75f3116aa30eb4958cc747f944f202ec69a484 (patch)
tree2afb99a17a2fe3c832c8eae0f0e7594ea806b7e9 /webAO/client
parentbd8b53cd6046cef9802d593d8257392d81afb5ce (diff)
Remove safeTags, decodeChat, and prepChat
Following the removal of innerHTML manipulation, we no longer need these sanitization functions. I've reviewed every safeTags call site to make sure the outputs don't end up anywhere unsafe, and malicious input can't malipulate DOM or execute code. These values either end up either as plain text (textContent, innerText, createTextNode, title, option) or as a URL path to request assets to the server (encoded using encodeURI). That is, if safeTags was even effective, considering all that function did was replace '<' and '>' symbols with Unicode lookalikes. Even the comment was suggesting the use of fundamentally safer functions instead of these hacks. Replace remaining uses of prepChat with unescapeChat as we still need to do the token substitution (like "<and>" to "&"). decodeChat was escaping Unicode sequences like \uXXXX, but I don't see the reason for this, AO2 Client doesn't have this feature, and considering WebSocket text frames are strictly UTF-8, we don't need these encodings.
Diffstat (limited to 'webAO/client')
-rw-r--r--webAO/client/addTrack.ts4
-rw-r--r--webAO/client/createArea.ts4
-rw-r--r--webAO/client/handleBans.ts2
-rw-r--r--webAO/client/handleCharacterInfo.ts25
4 files changed, 15 insertions, 20 deletions
diff --git a/webAO/client/addTrack.ts b/webAO/client/addTrack.ts
index 09ca049c..bba4b088 100644
--- a/webAO/client/addTrack.ts
+++ b/webAO/client/addTrack.ts
@@ -1,11 +1,11 @@
import { client } from "../client";
-import { unescapeChat, safeTags } from "../encoding";
+import { unescapeChat } from "../encoding";
import { getFilenameFromPath } from "../utils/paths";
export const addTrack = (trackname: string) => {
const newentry = <HTMLOptionElement>document.createElement("OPTION");
const songName = getFilenameFromPath(trackname);
- newentry.text = safeTags(unescapeChat(songName));
+ newentry.text = unescapeChat(songName);
newentry.value = trackname;
(<HTMLSelectElement>document.getElementById("client_musiclist")).options.add(
newentry,
diff --git a/webAO/client/createArea.ts b/webAO/client/createArea.ts
index a90b49ad..6bc00c00 100644
--- a/webAO/client/createArea.ts
+++ b/webAO/client/createArea.ts
@@ -1,9 +1,7 @@
import { client } from "../client";
import { area_click } from "../dom/areaClick";
-import { safeTags } from "../encoding";
-export const createArea = (id: number, aname: string) => {
- const name = safeTags(aname);
+export const createArea = (id: number, name: string) => {
const thisarea = {
name,
players: 0,
diff --git a/webAO/client/handleBans.ts b/webAO/client/handleBans.ts
index 4abd1f07..f9a005b3 100644
--- a/webAO/client/handleBans.ts
+++ b/webAO/client/handleBans.ts
@@ -1,5 +1,3 @@
-import { safeTags } from "../encoding";
-
/**
* Handles the kicked packet
* @param {string} type is it a kick or a ban
diff --git a/webAO/client/handleCharacterInfo.ts b/webAO/client/handleCharacterInfo.ts
index c7bcc943..278c6a75 100644
--- a/webAO/client/handleCharacterInfo.ts
+++ b/webAO/client/handleCharacterInfo.ts
@@ -1,5 +1,4 @@
import { client } from "../client";
-import { safeTags } from "../encoding";
import iniParse from "../iniParse";
import request from "../services/request";
import { AO_HOST } from "./aoHost";
@@ -22,17 +21,17 @@ export const setupCharacterBasic = (chargs: string[], charid: number) => {
const mute_select = <HTMLSelectElement>(
document.getElementById("mute_select")
);
- mute_select.add(new Option(safeTags(chargs[0]), String(charid)));
+ mute_select.add(new Option(chargs[0], String(charid)));
const pair_select = <HTMLSelectElement>(
document.getElementById("pair_select")
);
- pair_select.add(new Option(safeTags(chargs[0]), String(charid)));
+ pair_select.add(new Option(chargs[0], String(charid)));
// Store defaults — these get replaced with actual ini values by ensureCharIni
client.chars[charid] = {
- name: safeTags(chargs[0]),
- showname: safeTags(chargs[0]),
- desc: safeTags(chargs[1]),
+ name: chargs[0],
+ showname: chargs[0],
+ desc: chargs[1],
blips: "m",
gender: "",
side: "def",
@@ -86,14 +85,14 @@ export const ensureCharIni = async (charid: number): Promise<any> => {
cini.emotions = Object.assign(default_emotions, cini.emotions);
// Replace defaults with actual ini values
- char.showname = safeTags(cini.options.showname);
- char.blips = safeTags(cini.options.blips);
- char.gender = safeTags(cini.options.gender);
- char.side = safeTags(cini.options.side);
+ char.showname = cini.options.showname;
+ char.blips = cini.options.blips;
+ char.gender = cini.options.gender;
+ char.side = cini.options.side;
char.chat =
cini.options.chat === ""
- ? safeTags(cini.options.category)
- : safeTags(cini.options.chat);
+ ? cini.options.category
+ : cini.options.chat;
char.icon = img ? img.src : "";
char.inifile = cini;
@@ -124,7 +123,7 @@ export const handleCharacterInfo = async (chargs: string[], charid: number) => {
// Reset inifile so ensureCharIni will re-fetch
if (client.chars[charid]) {
- client.chars[charid].name = safeTags(chargs[0]);
+ client.chars[charid].name = chargs[0];
client.chars[charid].inifile = null;
} else {
setupCharacterBasic(chargs, charid);