JSON value with apostrophe [duplicate]
Asked Answered
P

3

6

I have an element with a rel attribute that contains a JSON string, something like:

rel='{"id":"#id#","name":"#name#"}'

Then, in my javascript code, I use $.parseJSON to parse this data. This works correctly - besides for cases where name contains an apostrophe. I've tried using jsStringFormat, a coldfusion replace that replaces all single quotes with escaped single quotes, etc, but I can't seem to hit on a correct solution. I know this is probably simple, but how do I get the code to correctly pass values with apostropes/single quotes using json?

This code works, but eliminates the apostrophes which I'd like to preserve:

rel='{"id":"#id#","name":"#replace(name,"'","","all")#"}'

This does not work:

rel='{"id":"#id#","name":"#replace(name,"'","\'","all")#"}'

Nor does:

rel='{"id":"#id#","name":"#replace(name,"'","\\\'","all")#"}'

Or:

rel='{"id":"#id#","name":"#replace(name,"'",""","all")#"}'

Or:

rel='{"id":"#id#","name":"#jsStringFormat(name)#"}'
Programme answered 27/8, 2012 at 19:38 Comment(2)
To properly escape double quotes in HTML attributes use "Gondar
Why can't you just use serializeJson?Weighin
P
4

After lots of playing around, I finally got this to work :)

rel='{"id":"#id#","name":"#replace(name,"'","&##39;","all")#"}'
Programme answered 27/8, 2012 at 20:10 Comment(1)
This answer is a hack and shouldn't be the recommended solution. It solves the issue with the apostrophe, but still allows other invalid characters in the output. e.g. if "name" has an ampersand in it. The correct answer is to properly encode strings for the context they are being used in.Margie
M
2

The issue you're having is because you are dealing with a string in two contexts. You need to make sure that the string is safe in both.

JSON string:

The easiest way to make the code JSON safe is to use SerializeJSON function to convert a ColdFusion object into valid JSON.

Thus your code could become:

rel='#SerializeJSON({"id"=Variables.id,"name"=Variables.name})#'

HTML attribute string:

The next context that you need to deal with is that you want the string to be a valid html attribute value.

In ColdFusion 10 you would handle this with the EncodeForHTMLAttribute function.

rel='#EncodeForHTMLAttribute(SerializeJSON({"id"=Variables.id,"name"=Variables.name}))#'

If you're using something prior to CF10 then using the ESAPI encoder is your best bet. (This was included with patches on some versions of ColdFusion)

rel='#CreateObject("java", "org.owasp.esapi.ESAPI").encoder().encodeForHTMLAttribute(SerializeJSON({"id"=Variables.id,"name"=Variables.name}))#'

I personally use a helper CFC to deal with ESAPI encoder in CF9, so CreateObject is only called once and reused for all uses of its methods.

Margie answered 28/8, 2012 at 11:47 Comment(0)
G
1

In JavaScript, escape single quotes in strings with \.

In HTML, you should really use double quotes for attributes though, and escape the double quotes, for example:

rel="{"id":"#id#","name":"#name#"}"
Gondar answered 27/8, 2012 at 19:45 Comment(7)
I'm using a coldfusion variable, not a literal. The pound signs denote the variableProgramme
@froadie: I've changed the example to reflect your variables.Gondar
that doesn't work, I don't think it's correct JSON syntaxProgramme
If you view the HTML source, what output are you getting from coldfusion?Gondar
it terminates the entire JSON string at the apostrophe in the nameProgramme
Apostrophes are valid in JSON and do not need to be escaped. See: #2275859Gondar
@Spolto Apostrophes are valid in JSON, but should be escaped in an HTML attribute. That's the issue that froadie is experiencing.Margie

© 2022 - 2024 — McMap. All rights reserved.