Skip to content

Commit d5a60b9

Browse files
Merge pull request #296 from SwiftFiddle/escape
Fix escaping HTML
2 parents c6e83fe + e06144e commit d5a60b9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1786
-1774
lines changed

Public/js/app.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,7 @@ export class App {
127127
.then((response) => response.json())
128128
.then((response) => {
129129
this.response = response;
130-
this.structureData = JSON.parse(
131-
response.syntaxJSON
132-
.replace(/&/g, "&")
133-
.replace(/</g, "&lt;")
134-
.replace(/>/g, "&gt;")
135-
.replace(/'/g, "&#039;")
136-
);
130+
this.structureData = JSON.parse(response.syntaxJSON);
137131

138132
this.updateStructure();
139133
this.updateLookup();

Public/js/structure_view.js

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -98,18 +98,10 @@ function makeTokenPopoverContent(data) {
9898

9999
makeSourceRangePopoverContent(data, dl);
100100

101-
makeDescriptionList("kind", stripHTMLTag(data.token.kind), dl);
102-
makeDescriptionList(
103-
"leadingTrivia",
104-
stripHTMLTag(data.token.leadingTrivia),
105-
dl
106-
);
107-
makeDescriptionList("text", stripHTMLTag(data.text), dl);
108-
makeDescriptionList(
109-
"trailingTrivia",
110-
stripHTMLTag(data.token.trailingTrivia),
111-
dl
112-
);
101+
makeDescriptionList("kind", data.token.kind, dl);
102+
makeDescriptionList("leadingTrivia", data.token.leadingTrivia, dl);
103+
makeDescriptionList("text", data.text, dl);
104+
makeDescriptionList("trailingTrivia", data.token.trailingTrivia, dl);
113105

114106
container.appendChild(dl);
115107

@@ -129,11 +121,11 @@ function makePropertyPopoverContent(property, list) {
129121
if (property.ref) {
130122
return `<span class="badge ref">${property.ref}</span>`;
131123
} else if (value && value.text && value.kind) {
132-
const text = stripHTMLTag(value.text);
133-
const kind = stripHTMLTag(value.kind);
124+
const text = value.text;
125+
const kind = value.kind;
134126
return `${text}<span class="badge rounded-pill">${kind}</span>`;
135127
} else if (value && value.text) {
136-
return stripHTMLTag(value.text);
128+
return value.text;
137129
}
138130
})();
139131
makeDescriptionList(property.name, details, list);
@@ -179,19 +171,3 @@ function makeSyntaxTypeBadge(type) {
179171
}
180172
return badge;
181173
}
182-
183-
function stripHTMLTag(text) {
184-
const div = document.createElement("div");
185-
div.innerHTML = text
186-
.replace(/&lt;/g, "<")
187-
.replace(/&gt;/g, ">")
188-
.replace(/&#039;/g, "'")
189-
.replace(/&amp;/g, "&");
190-
return escapeHTML(div.textContent || div.innerText || "");
191-
}
192-
193-
function escapeHTML(text) {
194-
const div = document.createElement("div");
195-
div.appendChild(document.createTextNode(text));
196-
return div.innerHTML;
197-
}

Resources/branch_main/Sources/parser/TokenVisitor.swift

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ final class TokenVisitor: SyntaxRewriter {
142142
}
143143

144144
override func visit(_ token: TokenSyntax) -> TokenSyntax {
145-
current.text = token.text
145+
current.text = escapeHTML(token.text)
146146
current.token = Token(kind: "\(token.tokenKind)", leadingTrivia: "", trailingTrivia: "")
147147

148148
token.leadingTrivia.forEach { (piece) in
@@ -183,7 +183,7 @@ final class TokenVisitor: SyntaxRewriter {
183183
let end = sourceRange.end
184184
let text = token.presence == .present ? token.text : ""
185185
list.append(
186-
"<span class='token \(kind)' " +
186+
"<span class='token \(escapeHTML(kind))' " +
187187
"data-title='\(escapeHTML("\(token.trimmed)"))' " +
188188
"data-content='\(escapeHTML("\(token.tokenKind)"))' " +
189189
"data-type='Token' " +
@@ -230,21 +230,21 @@ final class TokenVisitor: SyntaxRewriter {
230230
private func replaceSymbols(text: String) -> String {
231231
text.replacingOccurrences(of: "&nbsp;", with: "").replacingOccurrences(of: "<br>", with: "")
232232
}
233+
}
233234

234-
private func escapeHTML(_ string: String) -> String {
235-
var newString = string
236-
let specialCharacters = [
237-
("&", "&amp;"),
238-
("<", "&lt;"),
239-
(">", "&gt;"),
240-
("\"", "&quot;"),
241-
("'", "&apos;"),
242-
];
243-
for (unescaped, escaped) in specialCharacters {
244-
newString = newString.replacingOccurrences(of: unescaped, with: escaped, options: .literal, range: nil)
245-
}
246-
return newString
247-
.replacingOccurrences(of: " ", with: "&nbsp;")
248-
.replacingOccurrences(of: "\n", with: "<br>")
235+
func escapeHTML(_ string: String) -> String {
236+
var newString = string
237+
let specialCharacters = [
238+
("&", "&amp;"),
239+
("<", "&lt;"),
240+
(">", "&gt;"),
241+
("\"", "&quot;"),
242+
("'", "&apos;"),
243+
];
244+
for (unescaped, escaped) in specialCharacters {
245+
newString = newString.replacingOccurrences(of: unescaped, with: escaped, options: .literal, range: nil)
249246
}
247+
return newString
248+
.replacingOccurrences(of: " ", with: "&nbsp;")
249+
.replacingOccurrences(of: "\n", with: "<br>")
250250
}

Resources/branch_main/Sources/parser/TreeNode.swift

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ final class TreeNode: Codable {
1212

1313
init(id: Int, text: String, range: Range, type: SyntaxType) {
1414
self.id = id
15-
self.text = text
15+
self.text = escapeHTML(text)
1616
self.range = range
1717
self.type = type
1818
}
@@ -72,9 +72,13 @@ struct StructureProperty: Codable, Equatable {
7272
let ref: String?
7373

7474
init(name: String, value: StructureValue? = nil, ref: String? = nil) {
75-
self.name = name
75+
self.name = escapeHTML(name)
7676
self.value = value
77-
self.ref = ref
77+
if let ref {
78+
self.ref = escapeHTML(ref)
79+
} else {
80+
self.ref = nil
81+
}
7882
}
7983
}
8084

@@ -95,8 +99,12 @@ struct StructureValue: Codable, Equatable {
9599
let kind: String?
96100

97101
init(text: String, kind: String? = nil) {
98-
self.text = text
99-
self.kind = kind
102+
self.text = escapeHTML(text)
103+
if let kind {
104+
self.kind = escapeHTML(kind)
105+
} else {
106+
self.kind = nil
107+
}
100108
}
101109
}
102110

@@ -124,6 +132,12 @@ struct Token: Codable, Equatable {
124132
var kind: String
125133
var leadingTrivia: String
126134
var trailingTrivia: String
135+
136+
init(kind: String, leadingTrivia: String, trailingTrivia: String) {
137+
self.kind = escapeHTML(kind)
138+
self.leadingTrivia = leadingTrivia
139+
self.trailingTrivia = trailingTrivia
140+
}
127141
}
128142

129143
extension Token: CustomStringConvertible {

Resources/branch_main/Tests/Tests/Fixtures/test-1-1.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@
330330
{
331331
"name": "identifier",
332332
"value": {
333-
"kind": "identifier(\"number\")",
333+
"kind": "identifier(&quot;number&quot;)",
334334
"text": "number␣"
335335
}
336336
},
@@ -356,7 +356,7 @@
356356
"structure": [],
357357
"text": "number",
358358
"token": {
359-
"kind": "identifier(\"number\")",
359+
"kind": "identifier(&quot;number&quot;)",
360360
"leadingTrivia": "",
361361
"trailingTrivia": ""
362362
},
@@ -445,7 +445,7 @@
445445
{
446446
"name": "literal",
447447
"value": {
448-
"kind": "integerLiteral(\"0\")",
448+
"kind": "integerLiteral(&quot;0&quot;)",
449449
"text": "0"
450450
}
451451
},
@@ -471,7 +471,7 @@
471471
"structure": [],
472472
"text": "0",
473473
"token": {
474-
"kind": "integerLiteral(\"0\")",
474+
"kind": "integerLiteral(&quot;0&quot;)",
475475
"leadingTrivia": "",
476476
"trailingTrivia": ""
477477
},

0 commit comments

Comments
 (0)