Keyword modifier not escaping quotes within Snippet

(Lisa) #1

I’m trying to set the content of a metadata WYSIWYG field as a variable in a Server Side JavaScript block. The problem is that the metadata field contains Snippets and any escaping of quotes doesn’t seem to apply to the snippet. If I use something like:
var value = "%asset_metadata_blah^escapequotes%";
var value = "%asset_metadata_blah^replace:":\"%";
and the snippet contains a " then the JS breaks because the quote in the snippet isn’t being escaped. The regular content within the field is escaped fine, it’s just what’s in the snippet that’s the risk.

Has anyone else come across this?

Matrix Version:

(David Schoen) #2

^json_encode is what you want inside any JS context.

(John gill) #3

^json_encode (the better alternative) won’t help here because the issue is that the keyword contains a %globals_ keyword which doesn’t get evaluated until after the ^escapequotes modifier. If the globals keyword contains newlines or quotes, your JS is borked.

Half-fix is to use ^base64encode instead of ^json_encode, which at least obfuscates the result and prevents any %globals_ from being evaluated and breaking things.

var value = "%asset_metadata_blah^base64encode%";

Of course this way you’re stuck with an unprocessed %globals_snippet_ keyword in the string when it hits the browser. This is better than broken JS, but not by much.

I’ve had some success with using ^run_ssjs to force evaluation of keywords before the encoding step

var value = "%asset_metadata_blah^run_ssjs^base64encode%";

however I don’t know if this works in all cases when the value doesn’t actually contain any SSJS. I’ve seen it work, but I think I’ve also seen it not work, so I’m not sure on the limits of this approach.

(John gill) #4

Ok, it turns out that was lousy advice because the ^run_ssjs modifier appears only work on keywords which specify an assetid.

%globals_asset_contents_raw:19462^run_ssjs% works
%asset_metadata_content^run_ssjs% does not

Looking at the code, this appears to be a bug. I just hit it in, not sure if it’s fixed in later versions.

Without ^run_ssjs, I’m not aware of any way to:

  • Take a metadata value, and
  • Process any global keywords inside it, and
  • Safely encode it into a JS string in the page

(Lisa) #5

Thank you, David and John, for your suggestions. No joy unfortunately.
As John said, ^json_encode doesn’t help because the snippets aren’t evaluated yet. And ^run_ssjs really doesn’t like code without any SSJS in it! (And I just see John has already discovered this and replied while I’m still writing this.)

I’m stumped. :frowning:

(Bart Banda) #6

Do you need the snippet keyword to be evaluated at the time of setting it as a JS Var? If not, you could try and workaround it by doing something like

var value = "%asset_metadata_blah^replace:globals_snippet:foo_snippet%";
value = value.replace(/foo_snippet/g, 'globals_snippet');

That way whenever you print value, it will have the keyword un-replaced keyword but it will get replaced again before Matrix sends the content to the browser.

Alternatively you could just add the evalkeywords=“post” attribute to the script tag and not replace any keywords and leave them to be processed afterwards.