Skip to content

Commit

Permalink
enhance better escaping
Browse files Browse the repository at this point in the history
  • Loading branch information
andreasRu committed Aug 9, 2023
1 parent 44f8a1b commit 4f51ea2
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 4 deletions.
14 changes: 11 additions & 3 deletions components/HtmlHelper.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,23 @@ component {
result = result.reReplace( "<!--.*?-->", "", "all" ); // remove hardcoded html(multiline/singleline) comments
}



if( stripScriptAndCssComments ) {

result = result
.reReplace( "(\s*)\/\*(.|\n)*?\*\/", "", "all" ) // remove hardcoded javascript/css multiline comments;
.reReplace( "\s?(\/\/)(.*?)(\n|<\/script)", "\3", "all" ) // remove hardcoded javascript singleline comments
}
.reReplace( "(\s*)\/\*(.|\n)*?\*\/", " ", "all" ) // remove hardcoded javascript/css multiline comments;
.reReplace( "([\n|\r]+)\/\/.*?(\n|<\/script)", "\2", "all" ) // remove hardcoded javascript inline comments
.reReplace( "\s+\/\/.*?(\n|<\/script)", "\1", "all" ) // remove hardcoded javascript inline comments
}


elseif( compressWhitespaces ){
result = result.reReplace( "\s?(\/\/)(.*?)(\n|<\/script)", "/*\2*/\3", "all" ) // convert single line comments to multiline, otherwise it will break javascript
}



if( compressWhitespaces ) {
result = result.reReplace( "\s+", " ", "all" ); // compress all double tabs/spaces/newlines to single spaces
}
Expand Down
63 changes: 62 additions & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
@@ -1 +1,62 @@
<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta http-equiv="X-UA-Compatible" content="ie=edge"><meta name="theme-color" content="&#x23;017f8e"><meta name="description" content="HtmlHelper.cfc: minifyHtml() to get rid of CFML generated whitespace, or use encodeTrustedHtml() to encode HTML of a trusted source that has unencoded characters in inner Html"><meta name="robots" content="index,follow"><meta itemprop="name" content="minifyHtml() and encodeTrustedHtml() | A basic Html Helper Component for CFML"><meta property="og:url" content="https:</script><script> const elements = document.querySelectorAll('code'); elements.forEach((element) => { element.classList.add('language-html'); }); const aTags = document.querySelectorAll('a'); aTags.forEach((element) => { element.setAttribute('target', '_blank'); }); hljs.highlightAll(); </script></body></html>
<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta http-equiv="X-UA-Compatible" content="ie=edge"><meta name="theme-color" content="&#x23;017f8e"><meta name="description" content="HtmlHelper.cfc: minifyHtml() to get rid of CFML generated whitespace, or use encodeTrustedHtml() to encode HTML of a trusted source that has unencoded characters in inner Html"><meta name="robots" content="index,follow"><meta itemprop="name" content="minifyHtml() and encodeTrustedHtml() | A basic Html Helper Component for CFML"><meta property="og:url" content="https://andreasru.github.io/cfml-htmlhelper/"><meta property="og:title" content="minifyHtml() and encodeTrustedHtml() | A basic Html Helper Component for CFML"><meta property="og:type" content="website"><meta property="og:site_name" content="A basic Html Helper Component for CFML"><meta property="og:description" content="HtmlHelper.cfc: minifyHtml() to get rid of CFML generated whitespace, or use encodeTrustedHtml() to encode HTML of a trusted source that has unencoded characters in inner Html"><title>HtmlHelper.cfc&#x3a; minifyHtml&#x28;&#x29; &amp; encodeTrustedHtml&#x28;&#x29; in your CFML Projects</title><link rel="stylesheet" href="libs/normalizecss/normalize.min.css"><link rel="stylesheet" href="libs/highlightjs/highlightjs_styles_default.min.css"><link rel="stylesheet" href="libs/highlightjs/highlightjs_atom-one-dark.min.css"><link rel="stylesheet" href="libs/main.css"><link rel="stylesheet" href="libs/open-sans.css"></head><body><span id="forkongithub"><a href="https://github.com/andreasRu/cfml-htmlhelper"> Fork me on GitHub</a></span><h1>HtmlHelper.cfc &#x28;Vers. 0.9.2&#x29;</h1><hr /><p><strong><em>Minify your CFML generated HTML at runtime&#x21;</em></strong></p><p></p><h2>A simple basic CFML component to</h2><blockquote><ul><li><strong>minify CFML generated html</strong> content</li><li><strong>encode trusted HTML</strong> content containing non-compliant&#x2f;unescaped characters like e.g. &euro;, &uuml;, &ouml;, &szlig;, etc. within a tags inner HTML</li></ul></blockquote><h3>1. minifyHtml&#x28; string html required &#x29;</h3><h4>Converts a whitespace poluted HTML block like this</h4><pre><code> &lt;!DOCTYPE html&gt;
&lt;head&gt;
&lt;title&gt;Hot CFML Page &amp; content&lt;/title&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
&lt;style&gt; /* some comment
*/
.someClass{
font-size: 1rem; /* set font size */ } &lt;/style&gt;

&lt;meta name="description" content="Just some Example"&gt;
&lt;link rel="stylesheet" href="css/main.css"&gt;
&lt;/head&gt; &lt;body&gt;
&lt;!-- Say "Hello" to the CFML coders! --&gt; &lt;p&gt;Hello to all CFML devs 😀 🤩 around the 🌎!!! &lt;/p&gt;
&lt;script&gt; /* this is just some
embedded JavaScript */
console.log('Log Something'); // this is just some Javascript &lt;/script&gt; &lt;/body&gt; &lt;/html&gt;
</code></pre><h4>... into a minified HTML version like this</h4><pre><code>&lt;!DOCTYPE html&gt;&lt;head&gt;&lt;title&gt;Hot CFML Page &amp;amp; content&lt;/title&gt;&lt;meta charset="utf-8"&gt;&lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt;&lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;&lt;style&gt; .someClass{ font-size: 1rem; } &lt;/style&gt;&lt;meta name="description" content="Just some Example"&gt;&lt;link rel="stylesheet" href="css/main.css"&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;Hello to all CFML devs &amp;#x1f600; &amp;#x1f929; around the &amp;#x1f30e;&amp;#x21;&amp;#x21;&amp;#x21; &lt;/p&gt;&lt;script&gt; console.log('Log Something');&lt;/script&gt;&lt;/body&gt;&lt;/html&gt;
</code></pre><p>The function <code>minifyHtml()</code> minifies CFML generated html content by&#x3a;</p><blockquote><ul><li>stripping HTML comments</li><li>stripping JavaScript multline comments</li><li>stripping JavaScript singleline comments</li><li>stripping CSS comments</li><li>stripping whitespaces, such as all double tabs&#x2f;spaces&#x2f;newlines</li><li>honouring and preserving the content within <code>&lt;pre&gt;&lt;/pre&gt;</code> or <code>&lt;code&gt;&lt;/code&gt;</code> tags as submitted</li></ul></blockquote><p>Passing arguments to minifyHtml&#x28;&#x29; is possible &#x28;e.g <code>minifyHtml( htmlString=htmlBlock, stripHtmlComments=true )</code>&#x29;</p><blockquote><ul><li><strong>htmlString</strong><em>&#x28; string required &#x29;</em>&#x3a; a string containing the complete html code to be minified.</li><li><strong>stripScriptAndCssComments</strong><em>&#x28; boolean&#x2f;default&#x3d;true &#x29;</em>&#x3a; removes all comments between script and style tags. Single line JavaScript comments will be converted to multiline to not break JavaScript Functionality</li><li><strong>stripHtmlComments</strong><em>&#x28; boolean&#x2f;default&#x3d;true &#x29;</em>&#x3a; removes all HTML comments &#x28;e.g. <code>&lt;!-- My comment --&gt;</code>&#x29;</li><li><strong>compressWhitespaces</strong><em>&#x28; boolean&#x2f;default&#x3d;true &#x29;</em>&#x3a; compresses any multiple whitespaces &#x28;e.g. new lines, spaces or tabs &#x29; by unifying them to one single space, converting the passed html string from multiline to a single lined html block.</li><li><strong>stripEmptySpacesBetweenHtmlElements</strong><em>&#x28; boolean&#x2f;default&#x3d;true &#x29;</em>&#x3a; removes all whitespaces between html tags &#x28; e.g. from <code>&lt;div&gt; &lt;div&gt; Hello World &lt;span&gt; ! &lt;/span&gt; &lt;/div&gt; &lt;/div&gt;</code> results in <code>&lt;div&gt;&lt;div&gt; Hello World span&gt; ! &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;</code>&#x29;.</li></ul></blockquote><h3>2. encodeTrustedHTML&#x28; string trustedHtml required &#x29;&#59;</h3><h4>Converts HTML from a trusted source with unencoded characters like this</h4><pre><code>&lt;div class="someClass"&gt;
I tend to add "€, ä, &amp;, é, ß" and I
even might tend to add a &gt; (greater sign)
directly into my html 😲, because I'm
a lazy content writer and I don't like
adding those as html encoded characters manually!
&lt;/div&gt;
</code></pre><h4>... into proper html like this</h4><pre><code>&lt;div class="someClass"&gt; I tend to add &amp;quot;&amp;euro;, &amp;auml;, &amp;amp;, &amp;eacute;, &amp;szlig;&amp;quot; and I even might tend to add a &amp;gt; &amp;#x28;greater sign&amp;#x29; directly into my html &amp;#x1f632;, because I&amp;#x27;m a lazy content writer and I don&amp;#x27;t like adding those as html encoded characters manually&amp;#x21; &lt;/div&gt;
</code></pre><p>The function <code>encodeTrustedHTML()</code> detects and encodes unencoded characters, but preserves valid HTML-Entities and HTML-Tags already present in the submitted HTML.</p><h3>3. Examples</h3><p>Example of minifying a whitespace overfilled WordPress page with <code>minifyHtml()</code>&#x3a;</p><pre><code>&lt;!--- /examples/cfhttpMinifyHtml.cfm: minifyHtml() ---&gt;
&lt;!--- Make sure to override admin setting and read template with correct charset(UTF-8) ---&gt;
&lt;cfprocessingdirective pageEncoding="UTF-8"&gt;
&lt;cfscript&gt;
// get whitespace polluted wordpress page!
cfhttp(method="GET", charset="utf-8", url="https://news.microsoft.com/source/", result="result" ) {};

htmlHelperService=new components.HtmlHelper();
cfcontent( reset = "true" );
writeoutput(
htmlHelperService.minifyHtml( result.filecontent )
);
&lt;/cfscript&gt;
</code></pre><p>Example of encoding a trusted HTML block to escape unescaped characters with <code>encodeTrustedHtml()</code>&#x3a;</p><pre><code>&lt;!--- /examples/encodeTrustedHtml.cfm: encodeTrustedHtml() ---&gt;
&lt;!--- Make sure to override admin setting and read template with correct charset(UTF-8) ---&gt;
&lt;cfprocessingdirective pageEncoding="UTF-8"&gt;
&lt;cfsavecontent variable="someHtmlBlock"&gt;
&lt;div&gt;
I'm adding some unescaped HTML directly into my HTML!
I't doesn't matter if they have already been encoded or not.

E.g " &amp;amp; or &amp; " will both create the same source. Add
letters like ä, ö, Ä, ü, é, punctuations like ~, &gt;, ⁋, ※,
currencies like $, €, £, ¥, ₹, symbols like ©, ®, ™, Ω,
arrows like →, ↖, ↳, ⇗, emojis like 👋 🤚 🖐 ✋ and they will be encoded properly.
&lt;/div&gt;
&lt;/cfsavecontent&gt;
&lt;cfscript&gt;
htmlHelperService=new components.HtmlHelper();
cfcontent( reset = "true" );
writeoutput(
htmlHelperService.encodeTrustedHtml ( someHtmlBlock )
);
&lt;/cfscript&gt;
</code></pre><h3>4. Service Functions as Lambda Expression</h3><p><strong>HtmlHelper.cfc</strong> passes the functions minifyHtml&#x28;&#x29; and encodeTrustedHtml&#x28;&#x29; as Lambda Expressions to enhance inner local scoping &#x28;<a href="https://github.com/andreasRu/cfml-htmlhelper/blob/cc91c88a5e744a27d5006accb5ed9e54cd5e7dc5/components/HtmlHelper.cfc#L16">see code here at GitHub</a>&#x29;&#x3a;</p><p><img src="images/dumpStruct.webp" alt="cfml html minifier" /></p><h3>5. Tips &amp; Security Advisory</h3><blockquote><ul><li><strong>IMPORTANT SECURITY NOTICE&#x3a;</strong><code>encodeTrustedHtml()</code> MUST NOT be used to avoid XSS, because it only encodes unencoded characters of the inner HTML &#x28;within the body of tags&#x29;. This function will accept any submitted HTML, JavaScript and Styles and output it as submitted&#x28;&#x21;&#x29; without encoding it for XSS mitigation. For XSS prevention of untrusted HTML you <strong>MUST</strong> continue to use <code>encodeForHTML()</code>, <code>encodeForHTMLAttribute()</code>, <code>encodeForJavascript()</code>, <code>encodeFor...()</code> respectively.</li><li>The Regex patterns are set to work with CFMLs default &#x27;Perl&#x27; Regex-Engine</li><li>When using <code>encodeTrustedHTML()</code> always make sure to keep all the charsets among the stream &quot;in sync&quot;. Having different charsets for templates, web charset, charset http headers, or resource charsets may have unpredictable wrong html-entities and characters.</li><li><code>encodeTrustedHTML()</code> is typically used when you have a fronted CMS with a HTML-Editor where you can manually add custom HTML to a database.</li><li>You get best performance when you use <code>minifyHtml()</code> only once during the request flow, e.g. at the end of the CFML processing. A good location could be the <strong>Application.cfc</strong> at the end of the <code>onRequest()</code> function.</li></ul></blockquote><h3>6. Downloads</h3><blockquote><ul><li><strong>Raw HtmlHelper.cfc component</strong>&#x3a; <a href="https://raw.githubusercontent.com/andreasRu/cfml-htmlhelper/master/components/HtmlHelper.cfc">Download</a></li><li><strong>Repository as ZIP-File</strong>&#x3a; <a href="https://github.com/andreasRu/cfml-htmlhelper/archive/refs/heads/master.zip">Download</a></li><li><strong>Example minifyHtml&#x28;&#x29;</strong>&#x3a; <a href="https://raw.githubusercontent.com/andreasRu/cfml-htmlhelper/master/examples/minifyHtml.cfm">Download</a></li><li><strong>Example Cfhttp &amp; minifyHtml&#x28;&#x29;</strong>&#x3a; <a href="https://raw.githubusercontent.com/andreasRu/cfml-htmlhelper/master/examples/cfhttpMinifyHtml.cfm">Download</a></li><li><strong>Example encodeTrustedHTML&#x28;&#x29;</strong>&#x3a; <a href="https://raw.githubusercontent.com/andreasRu/cfml-htmlhelper/master/examples/encodeTrustedHtml.cfm">Download</a></li></ul></blockquote><h3>7. How to run the repository locally</h3><p>To test or watch the code running locally, you&#x27;ll need CommandBox as dependency&#x3a;</p><blockquote><ol><li>Download the <a href="https://github.com/andreasRu/cfml-htmlhelper/archive/refs/heads/master.zip">Repository as ZIP-File</a></li><li>Unzip it</li><li>Run <code>server.bat</code> on Windows or <code>server.sh</code>on MacOs&#x2f;Linux</li><li>Wait for commandBox open the browser and load the page</li></ol></blockquote><h3>8. Remarks</h3><p>I&#x27;m not taking anything for this but if you like or you&#x27;re using it, I kindly ask you to donate to the <strong>Lucee Organization</strong> to make this awesome cfengine even better&#x3a;</p><p><a href="https://opencollective.com/lucee">Lucee Open Collective Donation</a> &#x2764;&#xfe0f;</p><h3>9. About</h3><blockquote><ul><li><strong>Author&#x3a;</strong> Andreas at <a href="https://www.rhein-berg-digital.de">Rhein Berg Digital</a>, <a href="https://www.linkedin.com/in/claudio-andreas-r%C3%BCger-259000199/" target="_blank" rel="nofollow">LinkedIn</a></li><li><strong>GitHub&#x3a;</strong> &nbsp;<a href="https://github.com/andreasRu/cfml-htmlhelper">cfml-htmlhelper</a></li><li><strong>Issues&#x2f;Requests&#x3a;</strong> &nbsp;<a href="https://github.com/andreasRu/cfml-htmlhelper/issues">cfml-htmlhelper issues</a></li><li><strong>License&#x3a;</strong> &nbsp;<a href="https://github.com/andreasRu/cfml-htmlhelper/blob/master/LICENSE.txt">MIT License</a></li><li><strong>Software &#x3a;</strong>&nbsp;<a href="https://www.lucee.org/">Lucee CFML Engine</a> &#x28;GNU LGPL v2.1&#x29;, <a href="https://www.ortussolutions.com/products/commandbox">CommandBox</a> &#x28;GNU GPLv3&#x29;, <a href="https://highlightjs.org/">highlight.js</a> &#x28;BSD 3-Clause License, Copyright &#x28;c&#x29; 2006, Ivan Sagalaev&#x29;, <a href="https://github.com/necolas/normalize.css">normalize.css</a> &#x28;MIT License, Copyright &#x28;c&#x29; Nicolas Gallagher and Jonathan Neal&#x29;, <a href="https://codepo8.github.io/css-fork-on-github-ribbon/">github-fork-ribbon-css</a> &#x28;MIT License, Copyright &#x28;c&#x29; 2013 Simon Whitaker&#x29;</li><li><strong>Imprint&#x3a;</strong> &nbsp;<a href="https://www.rhein-berg-digital.de/en/andreasru-github-io-imprint">Visit here</a></li><li><strong>Privacy Policy&#x3a;</strong> &nbsp;<a href="https://docs.github.com/en/site-policy">Visit the hosters Site Policy</a> and the <a href="https://www.rhein-berg-digital.de/en/andreasru-github-io-privacy-policy">authors</a></li></ul></blockquote><p class="footer">Static version generated with the amazing&#x2764;&#xfe0f;<br><a href="https://www.lucee.org/">Lucee CFML Engine</a></p><script src="libs/highlightjs/highlight.min.js"></script><script> const elements = document.querySelectorAll('code'); elements.forEach((element) => { element.classList.add('language-html'); }); const aTags = document.querySelectorAll('a'); aTags.forEach((element) => { element.setAttribute('target', '_blank'); }); hljs.highlightAll(); </script></body></html>

0 comments on commit 4f51ea2

Please sign in to comment.