HTMLString icon indicating copy to clipboard operation
HTMLString copied to clipboard

HTMLString.Tag.head() does not escape HTML attribute values

Open cubiclesoft opened this issue 7 years ago • 6 comments
trafficstars

Example:

blah = new HTMLString.Tag('a', { 'href': '/test.html', 'data-test': JSON.stringify({'id': 12, 'test': 'This is a test'}) });
blah.head();

It currently outputs:

<a data-test="{"id":12,"test":"This is a test"}" href="/test.html">

It should output:

<a data-test="{&quot;id&quot;:12,&quot;test&quot;:&quot;This is a test&quot;}" href="/test.html">

Or similar.

cubiclesoft avatar Feb 17 '18 19:02 cubiclesoft

@cubiclesoft yeah rightly or wrongly the responsibility to encode/escape the value before setting it is the caller's - I imagine I did this for performance at the time since typically since the focus was on parsing HTML.

So you'd need to do something like:

blah = new HTMLString.Tag('a', { 'href': '/test.html', 'data-test': HTMLString.String.encode(JSON.stringify({'id': 12, 'test': 'This is a test'})) });
blah.head();

anthonyjb avatar Feb 17 '18 19:02 anthonyjb

Update: This doesn't appear to escape quotes :/ looking into.

anthonyjb avatar Feb 17 '18 19:02 anthonyjb

HTMLString.String.encode() doesn't escape quotes, which is probably why ContentEdit has its own function for element attributes that does escape quotes.

cubiclesoft avatar Feb 17 '18 19:02 cubiclesoft

The fastest HTML escape function I know of is this one:

HTMLString.String.encode = function(text) {
    var map = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#039;'
    };

    return text.replace(/[&<>"']/g, function(m) { return map[m]; });
};

No intermediate DOM element required. Found and adapted it from StackOverflow somewhere.

cubiclesoft avatar Feb 17 '18 19:02 cubiclesoft

Ah yep just found that as well, unless the value sits within a html value quotes shouldn't be escaped so that makes sense now. E.g <span>"</span> is preferable to <span>quot;</span>.

I'm pretty sure early on I looked into escaping mechanisms and basically, anything simple didn't have good coverage, anything will full coverage was huge (and external) and so I picked the simple route (e.g try to rely on the browser).

Probably need the option to flag if you want to escape double/single quotes rather than always converting them, e.g encode = function (text, escape_quotes).

anthonyjb avatar Feb 17 '18 20:02 anthonyjb

The other option here is to perhaps incorporate something like https://github.com/mathiasbynens/he which seems comprehensive and not too heavy.

anthonyjb avatar Feb 17 '18 20:02 anthonyjb