summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg <supahgreg@users.noreply.github.com>2025-10-10 19:35:33 -0500
committerGitHub <noreply@github.com>2025-10-10 19:35:33 -0500
commit92493059da37b3cbd7040f786b1129571e3893cc (patch)
treeab8964c558a080362f9c0e6af09edaef2bb13764
parent80668d4fd818d2f2876b0d505a034865681ee485 (diff)
parentbb08b0acd5dbdfba068fad5332ddf51b485fc477 (diff)
Merge pull request #35 from tt-rss/bugfix/code-scanning-js-findings
Address two JS code scanning findings
-rw-r--r--js/App.js59
-rw-r--r--js/CommonFilters.js2
-rwxr-xr-xjs/FeedTree.js11
-rwxr-xr-xjs/common.js4
4 files changed, 32 insertions, 44 deletions
diff --git a/js/App.js b/js/App.js
index 370391f86..33bd81d9a 100644
--- a/js/App.js
+++ b/js/App.js
@@ -411,40 +411,39 @@ const App = {
},
// htmlspecialchars()-alike for headlines data-content attribute
escapeHtml: function(p) {
- if (typeof p == "string") {
- const map = {
- '&': '&amp;',
- '<': '&lt;',
- '>': '&gt;',
- '"': '&quot;',
- "'": '&#039;'
- };
+ if (typeof p !== 'string')
+ return p;
- return p.replace(/[&<>"']/g, function(m) { return map[m]; });
- } else {
+ const map = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&quot;',
+ "'": '&#x27;',
+ '/': '&#x2F;',
+ };
+
+ return p.replace(/[&<>"'\/]/g, m => map[m]);
+ },
+ unescapeHtml: function(p) {
+ if (typeof p !== 'string' || p.indexOf('&') === -1)
return p;
- }
+
+ return p.replace(/&(?:amp|lt|gt|quot|#x27|#x2F|#039|#47);/g, function(entity) {
+ switch (entity) {
+ case '&amp;': return '&';
+ case '&lt;': return '<';
+ case '&gt;': return '>';
+ case '&quot;': return '"';
+ case '&#x27;': case '&#039;': return "'";
+ case '&#x2F;': case '&#47;': return '/';
+ default: return entity;
+ }
+ });
},
- // http://stackoverflow.com/questions/6251937/how-to-get-selecteduser-highlighted-text-in-contenteditable-element-and-replac
getSelectedText: function() {
- let text = "";
-
- if (typeof window.getSelection != "undefined") {
- const sel = window.getSelection();
- if (sel.rangeCount) {
- const container = document.createElement("div");
- for (let i = 0, len = sel.rangeCount; i < len; ++i) {
- container.appendChild(sel.getRangeAt(i).cloneContents());
- }
- text = container.innerHTML;
- }
- } else if (typeof document.selection != "undefined") {
- if (document.selection.type == "Text") {
- text = document.selection.createRange().textText;
- }
- }
-
- return text.stripTags();
+ const sel = window.getSelection();
+ return sel ? sel.toString().trim() : "";
},
displayIfChecked: function(checkbox, elemId) {
if (checkbox.checked) {
diff --git a/js/CommonFilters.js b/js/CommonFilters.js
index f6cc5a4e7..6d40373d6 100644
--- a/js/CommonFilters.js
+++ b/js/CommonFilters.js
@@ -527,6 +527,8 @@ const Filters = {
`);
if (!App.isPrefs()) {
+ // TODO: This section isn't working as expected (under Firefox 143, at least).
+ // `selectedText` is always empty at this point (tested by selecting some article text).
const selectedText = App.getSelectedText();
if (selectedText != "") {
diff --git a/js/FeedTree.js b/js/FeedTree.js
index 67d2a8035..683205579 100755
--- a/js/FeedTree.js
+++ b/js/FeedTree.js
@@ -237,16 +237,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/array", "dojo/co
return rc;
},
getLabel: function(item) {
- let name = String(item.name);
-
- /* Horrible */
- name = name.replace(/&quot;/g, "\"");
- name = name.replace(/&amp;/g, "&");
- name = name.replace(/&mdash;/g, "-");
- name = name.replace(/&lt;/g, "<");
- name = name.replace(/&gt;/g, ">");
-
- return name;
+ return App.unescapeHtml(item.name);
},
expandParentNodes: function(feed, is_cat, list) {
try {
diff --git a/js/common.js b/js/common.js
index 9635ab492..99cf52fa1 100755
--- a/js/common.js
+++ b/js/common.js
@@ -167,10 +167,6 @@ Array.prototype.uniq = function() {
return this.filter((v, i, a) => a.indexOf(v) === i);
};
-String.prototype.stripTags = function() {
- return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?(\/)?>|<\/\w+>/gi, '');
-}
-
/* exported xhr */
const xhr = {
_ts: 0,