6
6
import com .contentstack .utils .node .MarkType ;
7
7
import org .apache .commons .text .StringEscapeUtils ;
8
8
import org .json .JSONObject ;
9
+ import org .jsoup .Jsoup ;
10
+ import org .jsoup .nodes .Document ;
9
11
10
12
import java .util .*;
11
13
@@ -101,67 +103,70 @@ private String escapeInjectHtml(JSONObject nodeObj, String nodeType) {
101
103
public String renderNode (String nodeType , JSONObject nodeObject , NodeCallback callback ) {
102
104
String strAttrs = strAttrs (nodeObject );
103
105
String children = callback .renderChildren (nodeObject .optJSONArray ("children" ));
106
+ // Jsoup sanitization
107
+ Document sanitizedChildren = Jsoup .parse (children );
108
+ String cleanChildren = sanitizedChildren .body ().html ();
104
109
switch (nodeType ) {
105
110
case "p" :
106
- return "<p" + strAttrs + ">" + children + "</p>" ;
111
+ return "<p" + strAttrs + ">" + cleanChildren + "</p>" ;
107
112
case "a" :
108
- return "<a" + strAttrs + " href=\" " + escapeInjectHtml (nodeObject , "href" ) + "\" >" + children + "</a>" ;
113
+ return "<a" + strAttrs + " href=\" " + escapeInjectHtml (nodeObject , "href" ) + "\" >" + cleanChildren + "</a>" ;
109
114
case "img" :
110
115
String assetLink = getNodeStr (nodeObject , "asset-link" );
111
116
if (!assetLink .isEmpty ()) {
112
117
JSONObject attrs = nodeObject .optJSONObject ("attrs" );
113
118
if (attrs .has ("link" )) {
114
- return "<a href=\" " + escapeInjectHtml (nodeObject , "link" ) + "\" >" + "<img" + strAttrs + " src=\" " + escapeInjectHtml (nodeObject , "asset-link" ) + "\" />" + children + "</a>" ;
119
+ return "<a href=\" " + escapeInjectHtml (nodeObject , "link" ) + "\" >" + "<img" + strAttrs + " src=\" " + escapeInjectHtml (nodeObject , "asset-link" ) + "\" />" + cleanChildren + "</a>" ;
115
120
}
116
- return "<img" + strAttrs + " src=\" " + escapeInjectHtml (nodeObject , "asset-link" ) + "\" />" + children ;
121
+ return "<img" + strAttrs + " src=\" " + escapeInjectHtml (nodeObject , "asset-link" ) + "\" />" + cleanChildren ;
117
122
}
118
- return "<img" + strAttrs + " src=\" " + escapeInjectHtml (nodeObject , "src" ) + "\" />" + children ;
123
+ return "<img" + strAttrs + " src=\" " + escapeInjectHtml (nodeObject , "src" ) + "\" />" + cleanChildren ;
119
124
case "embed" :
120
- return "<iframe" + strAttrs + " src=\" " + escapeInjectHtml (nodeObject , "src" ) + "\" " + children + "</iframe>" ;
125
+ return "<iframe" + strAttrs + " src=\" " + escapeInjectHtml (nodeObject , "src" ) + "\" " + cleanChildren + "</iframe>" ;
121
126
case "h1" :
122
- return "<h1" + strAttrs + ">" + children + "</h1>" ;
127
+ return "<h1" + strAttrs + ">" + cleanChildren + "</h1>" ;
123
128
case "h2" :
124
- return "<h2" + strAttrs + ">" + children + "</h2>" ;
129
+ return "<h2" + strAttrs + ">" + cleanChildren + "</h2>" ;
125
130
case "h3" :
126
- return "<h3" + strAttrs + ">" + children + "</h3>" ;
131
+ return "<h3" + strAttrs + ">" + cleanChildren + "</h3>" ;
127
132
case "h4" :
128
- return "<h4" + strAttrs + ">" + children + "</h4>" ;
133
+ return "<h4" + strAttrs + ">" + cleanChildren + "</h4>" ;
129
134
case "h5" :
130
- return "<h5" + strAttrs + ">" + children + "</h5>" ;
135
+ return "<h5" + strAttrs + ">" + cleanChildren + "</h5>" ;
131
136
case "h6" :
132
- return "<h6" + strAttrs + ">" + children + "</h6>" ;
137
+ return "<h6" + strAttrs + ">" + cleanChildren + "</h6>" ;
133
138
case "ol" :
134
- return "<ol" + strAttrs + ">" + children + "</ol>" ;
139
+ return "<ol" + strAttrs + ">" + cleanChildren + "</ol>" ;
135
140
case "ul" :
136
- return "<ul" + strAttrs + ">" + children + "</ul>" ;
141
+ return "<ul" + strAttrs + ">" + cleanChildren + "</ul>" ;
137
142
case "li" :
138
- return "<li" + strAttrs + ">" + children + "</li>" ;
143
+ return "<li" + strAttrs + ">" + cleanChildren + "</li>" ;
139
144
case "hr" :
140
145
return "<hr" + strAttrs + " />" ;
141
146
case "table" :
142
- return "<table " + strAttrs + ">" + children + "</table>" ;
147
+ return "<table " + strAttrs + ">" + cleanChildren + "</table>" ;
143
148
case "thead" :
144
- return "<thead " + strAttrs + ">" + children + "</thead>" ;
149
+ return "<thead " + strAttrs + ">" + cleanChildren + "</thead>" ;
145
150
case "tbody" :
146
- return "<tbody" + strAttrs + ">" + children + "</tbody>" ;
151
+ return "<tbody" + strAttrs + ">" + cleanChildren + "</tbody>" ;
147
152
case "tfoot" :
148
- return "<tfoot" + strAttrs + ">" + children + "</tfoot>" ;
153
+ return "<tfoot" + strAttrs + ">" + cleanChildren + "</tfoot>" ;
149
154
case "tr" :
150
- return "<tr" + strAttrs + ">" + children + "</tr>" ;
155
+ return "<tr" + strAttrs + ">" + cleanChildren + "</tr>" ;
151
156
case "th" :
152
- return "<th" + strAttrs + ">" + children + "</th>" ;
157
+ return "<th" + strAttrs + ">" + cleanChildren + "</th>" ;
153
158
case "td" :
154
- return "<td" + strAttrs + ">" + children + "</td>" ;
159
+ return "<td" + strAttrs + ">" + cleanChildren + "</td>" ;
155
160
case "blockquote" :
156
- return "<blockquote" + strAttrs + ">" + children + "</blockquote>" ;
161
+ return "<blockquote" + strAttrs + ">" + cleanChildren + "</blockquote>" ;
157
162
case "code" :
158
- return "<code" + strAttrs + ">" + children + "</code>" ;
163
+ return "<code" + strAttrs + ">" + cleanChildren + "</code>" ;
159
164
case "reference" :
160
165
return "" ;
161
166
case "fragment" :
162
- return "<fragment" + strAttrs + ">" + children + "</fragment>" ;
167
+ return "<fragment" + strAttrs + ">" + cleanChildren + "</fragment>" ;
163
168
default :
164
- return children ;
169
+ return cleanChildren ;
165
170
}
166
171
}
167
172
@@ -182,6 +187,16 @@ String strAttrs(JSONObject nodeObject) {
182
187
for (String key : attrsObject .keySet ()) {
183
188
Object objValue = attrsObject .opt (key );
184
189
String value = objValue .toString ();
190
+
191
+ StringBuilder escapedValue = new StringBuilder ();
192
+ for (char ch : value .toCharArray ()) {
193
+ if (ch == '&' || ch == '<' || ch == '>' || ch == '"' || ch == '\'' ) {
194
+ escapedValue .append ("&#" ).append ((int ) ch ).append (';' );
195
+ } else {
196
+ escapedValue .append (ch );
197
+ }
198
+ }
199
+ value = escapedValue .toString ();
185
200
// If style is available, do styling calculations
186
201
if (Objects .equals (key , "style" )) {
187
202
String resultStyle = stringifyStyles (attrsObject .optJSONObject ("style" ));
0 commit comments