Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2013-02-01 15:30:44

joebaich
Member
From: DC Metro Area and elsewhere
Registered: 2006-09-24
Posts: 507
Website

Textile - Escaping Ampersands

I want to use a version of this JS snippet, $("h2,h3").replaceText( /&/gi, '<b class="ampersand">' + '&' + '</b>' );, in conjunction with the jQuery Replacetext plugin to wrap ampersands in TXP article headings for CSS styling. The challenge is, of course that Textile replaces the Ampersand (&) with its HTML entity &amp;. I guess that the problem is that I don’t know how to escape or otherwise correctly deal with HTML entities. For instance, $("h2,h3").replaceText( /&amp;/gi, '<b class="ampersand">' + '&amp;' + '</b>' ); doesn’t work for me. Any ideas?

I do know about the plugin aam_typogrify that does much the same thing but I prefer the jQuery Replacetext approach because I will use it for other tasks in the same site.

Last edited by joebaich (2013-02-01 15:37:53)

Offline

#2 2013-02-01 16:00:12

maniqui
Member
From: Buenos Aires, Argentina
Registered: 2004-10-10
Posts: 3,070
Website

Re: Textile - Escaping Ampersands

I’m not sure where exactly are you adding that snippet so that it’s getting processed by Textile. Are you putting it directly in the article body/excerpt?
In other words, why is it getting processed by Textile?

In any case, you could try starting the line with notextile.:

notextile. $("h2,h3").replaceText( /&/gi, '<b class="ampersand">' + '&' + '</b>' );

But, also, in any case, and if I’m not wrong, you have to escape the ampersand when using it on Javascript code.


La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

#3 2013-02-01 16:24:30

joebaich
Member
From: DC Metro Area and elsewhere
Registered: 2006-09-24
Posts: 507
Website

Re: Textile - Escaping Ampersands

Hello Julián, Sorry for not being too clear, the snippet is in a js file so not processed by Textile, that wasn’t the issue. The challenge arises from the text ‘&’ that Textile processes into &amp;. I want it to process the ‘h2’ and ‘h3’ so no question of using notextile.

However, I have figured it out, though I don’t understand it: $("h2,h3").replaceText( /&/gi, '<b class="ampersand">' + '&amp;' + '</b>' ); works just fine and I can style up the fancy ampersand I am after in the headings e.g.

Offline

#4 2013-02-02 01:17:39

maniqui
Member
From: Buenos Aires, Argentina
Registered: 2004-10-10
Posts: 3,070
Website

Re: Textile - Escaping Ampersands

Hi Joe. My fault, I misread your post.
Cool that you solved it.

However, I have figured it out, though I don’t understand it: $(“h2,h3”).replaceText( /&/gi, ‘<b class=“ampersand”>’ + ‘&amp;’ + ‘</b>’ ); works just fine and I can style up the fancy ampersand I am after in the headings e.g.

After reading some documentation I can’t tell you exactly why is sufficient to just use & on the search argument. I’d assume that the replace String method works over the characters (replacement text of an HTML entity), not the HTML entity itself. But I’d like for someone to come and explain it clearly.


La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

#5 2013-02-02 04:48:25

Gocom
Developer Emeritus
From: Helsinki, Finland
Registered: 2006-07-14
Posts: 4,533
Website

Re: Textile - Escaping Ampersands

This isn’t related to string.replace(), or to HTML or JavaScript in general. As JavaScript and HTML go together, JavaScript doesn’t exactly care about HTML at all; it’s internals do not interpreter it, it’s internals have no relation to it. To JavaScript, HTML entity in a string is just of blob of data.

It has to do what the jQuery.fn.replaceText searches and alters; document’s text nodes. It picks up matching text nodes, does needed modifications to it and overwrites the original text node value. In case the new value contains HTML, it passes the job to jQuery.fn.before() which takes care of modifying the innerHTML.

Speaking of which, I do hope the text node to innerHTML conversion works for you. If I’m not mistaken it can and should be causing issues. Mainly, it should be stripping away any encoding from the original HTML contents, turning any encoded HTML control character to actual executed HTML. Not very good thing.

Offline

#6 2013-02-02 14:39:40

maniqui
Member
From: Buenos Aires, Argentina
Registered: 2004-10-10
Posts: 3,070
Website

Re: Textile - Escaping Ampersands

Gocom wrote:

This isn’t related to string.replace(), or to HTML or JavaScript in general. As JavaScript and HTML go together, JavaScript doesn’t exactly care about HTML at all; it’s internals do not interpreter it, it’s internals have no relation to it. To JavaScript, HTML entity in a string is just of blob of data.

If I got you right, you are explaining why /&/gi matches, well, &, even if the underlying HTML entity is &amp;.
I’ve created this jsfiddle to do some quick tests. It works too if using the Unicode representation/encoding for ampersands ( \u0026).

Speaking of which, I do hope the text node to innerHTML conversion works for you. If I’m not mistaken it can and should be causing issues. Mainly, it should be stripping away any encoding from the original HTML contents, turning any encoded HTML control character to actual executed HTML. Not very good thing.

According to example 3 on plugin documentation, using the plugin to replace text with HTML is expected, which, of course, doesn’t mean at all that it couldn’t be causing issues (which ones?), as you point out.


La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

#7 2013-02-02 21:33:24

Gocom
Developer Emeritus
From: Helsinki, Finland
Registered: 2006-07-14
Posts: 4,533
Website

Re: Textile - Escaping Ampersands

maniqui wrote:

If I got you right, you are explaining why /&/gi matches, well, &, even if the underlying HTML entity is &amp;.

You are not searching HTML, but text nodes from the document. A text node will not be containing HTML, but the parsed contents as text.

It works too if using the Unicode representation/encoding for ampersands ( \u0026).

Well, kinda obviously. For a document that is served as UTF-8 that would be the character.

doesn’t mean at all that it couldn’t be causing issues (which ones?), as you point out.

Well, to be clear, the encoding stripping mean its insecure as hell. Opening up nice XSS vulnerabilities and domain-restriction free CSRF vectors.

Let’s say that for instance some one left a forum post, or you write an article, with the resulting heading like this:

<h2>Explaining &lt;script&gt;alert('sup');&lt;/script&gt; &amp; security</h2>

As you can see the included example script is encoded, just harmless text, not actual markup. But when you run the plugin to it while adding HTML contents:

$('h2').replaceText( /&/gi, '<b class="ampersand">&amp;</b>' );

It’s get executed as the text node will be inserted as a innerHTML to the document, taking away any sanitization that used to be in place. Which is not good at all. The plugin is far from ideal.

Last edited by Gocom (2013-02-02 21:35:13)

Offline

#8 2013-02-02 22:06:52

maniqui
Member
From: Buenos Aires, Argentina
Registered: 2004-10-10
Posts: 3,070
Website

Re: Textile - Escaping Ampersands

Cool, thanks for the explanation, once again.


La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

#9 2013-02-03 00:47:37

Gocom
Developer Emeritus
From: Helsinki, Finland
Registered: 2006-07-14
Posts: 4,533
Website

Re: Textile - Escaping Ampersands

In short — Joe, please do not use that replaceText plugin. It is not that safe to use. My apologies, for initially not making that utmost clear.

With it running on the page, an attacker can potentially use it’s vulnerabilities/behavior to run 3rd-party code on your pages — opening a XSS vector. This in return would enable attacking your visitors with client-side exploits or executing domain-restriction free CSRF attacks (granting access to Textpattern admin-side, or any visitor’s user-accounts). So please, don’t use it.

If you do want to do simple search and replace operations in a flatten HTML tree, you can do that safely and very easily with just jQuery’s own basic DOM manipulation methods, like the html. A small example:

$('h2, h3').each(function () {
	var newValue = $(this).html().replace('&amp;', '<b>&amp;</b>');
	$(this).html(newValue);
});

Last edited by Gocom (2013-02-03 00:49:25)

Offline

#10 2013-02-03 04:22:34

joebaich
Member
From: DC Metro Area and elsewhere
Registered: 2006-09-24
Posts: 507
Website

Re: Textile - Escaping Ampersands

Gocom wrote:

In short — Joe, please do not use that replaceText plugin. It is not that safe to use. My apologies, for initially not making that utmost clear.

You did make it pretty clear first time, so with that and the realisation that some minimal jQuery could do the job, I had found something similar, but your snippet is significantly better and I am in your debt, doubly so because I have learned some vital things. Thank you for laying it out so clearly.

Last edited by joebaich (2013-02-03 14:05:31)

Offline

Board footer

Powered by FluxBB