|
34 | 34 |
|
35 | 35 | const THEME_STATES = ['auto', 'light', 'dark']; |
36 | 36 |
|
| 37 | + /// https://stackoverflow.com/a/6234804/4479969 |
| 38 | + const escapeHtml = unsafe => { |
| 39 | + if (typeof unsafe !== 'string') unsafe = String(unsafe); |
| 40 | + return unsafe |
| 41 | + .replaceAll("&", "&") |
| 42 | + .replaceAll("<", "<") |
| 43 | + .replaceAll(">", ">") |
| 44 | + .replaceAll('"', """) |
| 45 | + .replaceAll("'", "'"); |
| 46 | + }; |
| 47 | + |
37 | 48 | class CommandHistoryEntry { |
38 | 49 | constructor(text) { |
39 | 50 | this.text = text; |
|
211 | 222 | commandHistoryEntryBtn.type = 'button'; |
212 | 223 | let time_str = new Date(commandHistoryEntry.time).toLocaleString(); |
213 | 224 | commandHistoryEntryBtn.innerHTML = ` |
214 | | - <span class="command-history-entry-time">${time_str}</span> |
215 | | - <span class="command-history-entry-text">${commandHistoryEntry.text}</span> |
216 | | - <span class="command-history-entry-count">×${commandHistoryEntry.count}</span> |
| 225 | + <span class="command-history-entry-time">${escapeHtml(time_str)}</span> |
| 226 | + <span class="command-history-entry-text">${escapeHtml(commandHistoryEntry.text)}</span> |
| 227 | + <span class="command-history-entry-count">×${escapeHtml(commandHistoryEntry.count)}</span> |
217 | 228 | `; |
218 | 229 | commandHistoryEntryBtn.addEventListener('click', () => { |
219 | 230 | if (uiCommandLineInput.disabled) return; |
|
247 | 258 |
|
248 | 259 | clearCommandHistory() { |
249 | 260 | this.commandHistory = []; |
250 | | - uiCommandHistoryScrollbox.innerHTML = ''; |
| 261 | + uiCommandHistoryScrollbox.textContent = ''; |
251 | 262 | localStorage.removeItem('commandHistory'); |
252 | 263 | this.setStatus('Command history cleared', 'info'); |
253 | 264 | } |
|
322 | 333 | let receivedDataEntryBtn = document.createElement('div'); |
323 | 334 | receivedDataEntryBtn.className = 'received-data-entry'; |
324 | 335 | receivedDataEntryBtn.innerHTML = ` |
325 | | - <span class="received-data-entry-time">${new Date(entry.time).toLocaleString()}</span> |
326 | | - <span class="received-data-entry-text">${entry.text}</span> |
| 336 | + <span class="received-data-entry-time">${escapeHtml(new Date(entry.time).toLocaleString())}</span> |
| 337 | + <span class="received-data-entry-text">${escapeHtml(entry.text)}</span> |
327 | 338 | `; |
328 | 339 | documentFragment.appendChild(receivedDataEntryBtn); |
329 | 340 | } |
|
352 | 363 |
|
353 | 364 | clearReceivedData() { |
354 | 365 | this.receivedData = []; |
355 | | - uiReceivedDataScrollbox.innerHTML = ''; |
| 366 | + uiReceivedDataScrollbox.textContent = ''; |
356 | 367 | localStorage.removeItem('receivedData'); |
357 | 368 | this.setStatus('Received data cleared', 'info'); |
358 | 369 | } |
|
0 commit comments