diff --git a/examples/device/webusb_serial/website/application.js b/examples/device/webusb_serial/website/application.js index a6bb3f890..5e9dbf471 100644 --- a/examples/device/webusb_serial/website/application.js +++ b/examples/device/webusb_serial/website/application.js @@ -34,6 +34,17 @@ const THEME_STATES = ['auto', 'light', 'dark']; + /// https://stackoverflow.com/a/6234804/4479969 + const escapeHtml = unsafe => { + if (typeof unsafe !== 'string') unsafe = String(unsafe); + return unsafe + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll('"', """) + .replaceAll("'", "'"); + }; + class CommandHistoryEntry { constructor(text) { this.text = text; @@ -211,9 +222,9 @@ commandHistoryEntryBtn.type = 'button'; let time_str = new Date(commandHistoryEntry.time).toLocaleString(); commandHistoryEntryBtn.innerHTML = ` - ${time_str} - ${commandHistoryEntry.text} - ×${commandHistoryEntry.count} + ${escapeHtml(time_str)} + ${escapeHtml(commandHistoryEntry.text)} + ×${escapeHtml(commandHistoryEntry.count)} `; commandHistoryEntryBtn.addEventListener('click', () => { if (uiCommandLineInput.disabled) return; @@ -247,7 +258,7 @@ clearCommandHistory() { this.commandHistory = []; - uiCommandHistoryScrollbox.innerHTML = ''; + uiCommandHistoryScrollbox.textContent = ''; localStorage.removeItem('commandHistory'); this.setStatus('Command history cleared', 'info'); } @@ -322,8 +333,8 @@ let receivedDataEntryBtn = document.createElement('div'); receivedDataEntryBtn.className = 'received-data-entry'; receivedDataEntryBtn.innerHTML = ` - ${new Date(entry.time).toLocaleString()} - ${entry.text} + ${escapeHtml(new Date(entry.time).toLocaleString())} + ${escapeHtml(entry.text)} `; documentFragment.appendChild(receivedDataEntryBtn); } @@ -352,7 +363,7 @@ clearReceivedData() { this.receivedData = []; - uiReceivedDataScrollbox.innerHTML = ''; + uiReceivedDataScrollbox.textContent = ''; localStorage.removeItem('receivedData'); this.setStatus('Received data cleared', 'info'); }