-
-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathhtml-escape.sh
More file actions
executable file
·82 lines (78 loc) · 2.63 KB
/
Copy pathhtml-escape.sh
File metadata and controls
executable file
·82 lines (78 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/env bash
# html-escape.sh — Shared HTML escape primitives for the visual artifact
# layer. Used by bin/render-artifact.sh. Centralizing the escape rules
# here makes the security contract testable: ci/check-visual-artifact-
# templates.sh greps for direct printf of JSON values and fails if the
# escape helpers are bypassed.
#
# Public functions (stdin -> stdout):
# nano_html_escape text content. & < > " ' -> entities. Preserves newlines.
# nano_attr_escape attribute content. Same set; stricter quoting.
# nano_json_string string -> JSON-encoded literal (without surrounding quotes).
# Used by the manifest writer when piping shell
# strings into JSON without a jq round-trip.
if [ "${_NANO_HTML_ESCAPE_LOADED:-0}" = "1" ]; then
return 0 2>/dev/null || true
fi
_NANO_HTML_ESCAPE_LOADED=1
# Escape & < > " ' via awk. Replaces ampersand FIRST so later
# replacements do not double-encode the entity prefix. Reads stdin and
# writes to stdout. Newlines pass through untouched.
nano_html_escape() {
awk '
BEGIN { OFS = "" }
{
gsub(/&/, "\\&")
gsub(/</, "\\<")
gsub(/>/, "\\>")
gsub(/"/, "\\"")
gsub(/\047/, "\\'")
print
}
'
}
# Attribute content uses the same character set. Kept as a separate
# function so future hardening (for example, encoding the equals sign
# or backtick inside attribute context) lands in one place. Reads
# stdin and writes to stdout.
nano_attr_escape() {
awk '
BEGIN { OFS = "" }
{
gsub(/&/, "\\&")
gsub(/</, "\\<")
gsub(/>/, "\\>")
gsub(/"/, "\\"")
gsub(/\047/, "\\'")
print
}
'
}
# JSON-string escape. We delegate to jq when available because jq
# already implements the full RFC 8259 escape set (control characters,
# \uXXXX for non-ASCII). The output includes surrounding double
# quotes; callers strip them with `${var:1:-1}` when embedding inside
# a larger jq filter, or use the quoted form for raw concatenation.
nano_json_string() {
if command -v jq >/dev/null 2>&1; then
jq -Rs '.'
else
# Minimal fallback. Escapes the characters that break JSON strings.
# Loses control-character handling beyond newline; that is
# acceptable because the visual layer pipes everything through jq
# when jq is on PATH, which is a Nanostack requirement enforced
# elsewhere.
awk '
BEGIN { ORS = ""; printf "\"" }
{
s = $0
gsub(/\\/, "\\\\", s)
gsub(/"/, "\\\"", s)
gsub(/\t/, "\\t", s)
printf "%s", s
printf "\\n"
}
END { printf "\"\n" }
'
fi
}