66import com .contentstack .utils .node .MarkType ;
77import org .apache .commons .text .StringEscapeUtils ;
88import org .json .JSONObject ;
9+ import org .jsoup .Jsoup ;
10+ import org .jsoup .nodes .Document ;
911
1012import java .util .*;
1113
@@ -101,67 +103,70 @@ private String escapeInjectHtml(JSONObject nodeObj, String nodeType) {
101103 public String renderNode (String nodeType , JSONObject nodeObject , NodeCallback callback ) {
102104 String strAttrs = strAttrs (nodeObject );
103105 String children = callback .renderChildren (nodeObject .optJSONArray ("children" ));
106+ // Jsoup sanitization
107+ Document sanitizedChildren = Jsoup .parse (children );
108+ String cleanChildren = sanitizedChildren .body ().html ();
104109 switch (nodeType ) {
105110 case "p" :
106- return "<p" + strAttrs + ">" + children + "</p>" ;
111+ return "<p" + strAttrs + ">" + cleanChildren + "</p>" ;
107112 case "a" :
108- return "<a" + strAttrs + " href=\" " + escapeInjectHtml (nodeObject , "href" ) + "\" >" + children + "</a>" ;
113+ return "<a" + strAttrs + " href=\" " + escapeInjectHtml (nodeObject , "href" ) + "\" >" + cleanChildren + "</a>" ;
109114 case "img" :
110115 String assetLink = getNodeStr (nodeObject , "asset-link" );
111116 if (!assetLink .isEmpty ()) {
112117 JSONObject attrs = nodeObject .optJSONObject ("attrs" );
113118 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>" ;
115120 }
116- return "<img" + strAttrs + " src=\" " + escapeInjectHtml (nodeObject , "asset-link" ) + "\" />" + children ;
121+ return "<img" + strAttrs + " src=\" " + escapeInjectHtml (nodeObject , "asset-link" ) + "\" />" + cleanChildren ;
117122 }
118- return "<img" + strAttrs + " src=\" " + escapeInjectHtml (nodeObject , "src" ) + "\" />" + children ;
123+ return "<img" + strAttrs + " src=\" " + escapeInjectHtml (nodeObject , "src" ) + "\" />" + cleanChildren ;
119124 case "embed" :
120- return "<iframe" + strAttrs + " src=\" " + escapeInjectHtml (nodeObject , "src" ) + "\" " + children + "</iframe>" ;
125+ return "<iframe" + strAttrs + " src=\" " + escapeInjectHtml (nodeObject , "src" ) + "\" " + cleanChildren + "</iframe>" ;
121126 case "h1" :
122- return "<h1" + strAttrs + ">" + children + "</h1>" ;
127+ return "<h1" + strAttrs + ">" + cleanChildren + "</h1>" ;
123128 case "h2" :
124- return "<h2" + strAttrs + ">" + children + "</h2>" ;
129+ return "<h2" + strAttrs + ">" + cleanChildren + "</h2>" ;
125130 case "h3" :
126- return "<h3" + strAttrs + ">" + children + "</h3>" ;
131+ return "<h3" + strAttrs + ">" + cleanChildren + "</h3>" ;
127132 case "h4" :
128- return "<h4" + strAttrs + ">" + children + "</h4>" ;
133+ return "<h4" + strAttrs + ">" + cleanChildren + "</h4>" ;
129134 case "h5" :
130- return "<h5" + strAttrs + ">" + children + "</h5>" ;
135+ return "<h5" + strAttrs + ">" + cleanChildren + "</h5>" ;
131136 case "h6" :
132- return "<h6" + strAttrs + ">" + children + "</h6>" ;
137+ return "<h6" + strAttrs + ">" + cleanChildren + "</h6>" ;
133138 case "ol" :
134- return "<ol" + strAttrs + ">" + children + "</ol>" ;
139+ return "<ol" + strAttrs + ">" + cleanChildren + "</ol>" ;
135140 case "ul" :
136- return "<ul" + strAttrs + ">" + children + "</ul>" ;
141+ return "<ul" + strAttrs + ">" + cleanChildren + "</ul>" ;
137142 case "li" :
138- return "<li" + strAttrs + ">" + children + "</li>" ;
143+ return "<li" + strAttrs + ">" + cleanChildren + "</li>" ;
139144 case "hr" :
140145 return "<hr" + strAttrs + " />" ;
141146 case "table" :
142- return "<table " + strAttrs + ">" + children + "</table>" ;
147+ return "<table " + strAttrs + ">" + cleanChildren + "</table>" ;
143148 case "thead" :
144- return "<thead " + strAttrs + ">" + children + "</thead>" ;
149+ return "<thead " + strAttrs + ">" + cleanChildren + "</thead>" ;
145150 case "tbody" :
146- return "<tbody" + strAttrs + ">" + children + "</tbody>" ;
151+ return "<tbody" + strAttrs + ">" + cleanChildren + "</tbody>" ;
147152 case "tfoot" :
148- return "<tfoot" + strAttrs + ">" + children + "</tfoot>" ;
153+ return "<tfoot" + strAttrs + ">" + cleanChildren + "</tfoot>" ;
149154 case "tr" :
150- return "<tr" + strAttrs + ">" + children + "</tr>" ;
155+ return "<tr" + strAttrs + ">" + cleanChildren + "</tr>" ;
151156 case "th" :
152- return "<th" + strAttrs + ">" + children + "</th>" ;
157+ return "<th" + strAttrs + ">" + cleanChildren + "</th>" ;
153158 case "td" :
154- return "<td" + strAttrs + ">" + children + "</td>" ;
159+ return "<td" + strAttrs + ">" + cleanChildren + "</td>" ;
155160 case "blockquote" :
156- return "<blockquote" + strAttrs + ">" + children + "</blockquote>" ;
161+ return "<blockquote" + strAttrs + ">" + cleanChildren + "</blockquote>" ;
157162 case "code" :
158- return "<code" + strAttrs + ">" + children + "</code>" ;
163+ return "<code" + strAttrs + ">" + cleanChildren + "</code>" ;
159164 case "reference" :
160165 return "" ;
161166 case "fragment" :
162- return "<fragment" + strAttrs + ">" + children + "</fragment>" ;
167+ return "<fragment" + strAttrs + ">" + cleanChildren + "</fragment>" ;
163168 default :
164- return children ;
169+ return cleanChildren ;
165170 }
166171 }
167172
@@ -182,6 +187,16 @@ String strAttrs(JSONObject nodeObject) {
182187 for (String key : attrsObject .keySet ()) {
183188 Object objValue = attrsObject .opt (key );
184189 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 ();
185200 // If style is available, do styling calculations
186201 if (Objects .equals (key , "style" )) {
187202 String resultStyle = stringifyStyles (attrsObject .optJSONObject ("style" ));
0 commit comments