Skip to content

Instantly share code, notes, and snippets.

@skratchdot
Created May 17, 2011 02:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skratchdot/975802 to your computer and use it in GitHub Desktop.
Save skratchdot/975802 to your computer and use it in GitHub Desktop.
JSONP: Always escape U+2028 and U+2029 in ColdFusion. See: https://github.com/rack/rack-contrib/pull/37 and http://timelessrepo.com/json-isnt-a-javascript-subset
<cfparam name="url.chr" type="numeric" default="40" />
<cfparam name="url.useCustomFunction" type="boolean" default="false" />
<cfsilent>
<cfset myStruct = StructNew() />
<cfset myStruct["myString"] = ":DEC:[#url.chr#] - :CHR:[#chr(url.chr)#]." />
<cfif url.useCustomFunction>
<cfset myJSON = SafeSerializeJSON(myStruct) />
<cfelse>
<cfset myJSON = SerializeJSON(myStruct) />
</cfif>
</cfsilent>
<cfoutput><html>
<head>
<title>JSON Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div>HTML Output:</div>
<div>#myStruct.myString#</div>
<hr />
<div>Javascript Output:</div>
<div id="jsOutput"><span style="color:##c00">ERROR</span></div>
<script type="text/javascript">
var myVar = #myJSON#;
document.getElementById('jsOutput').innerHTML = myVar.myString;
</script>
<script type="text/javascript">
document.write('wow<br />');
</script>
<hr />
<form action="json.cfm" method="get">
<input type="input" name="chr" value="#HTMLEditFormat(url.chr)#" />
<select name="useCustomFunction">
<option value="false"<cfif url.useCustomFunction eq false> selected="selected"</cfif>>SerializeJSON()</option>
<option value="true"<cfif url.useCustomFunction eq true> selected="selected"</cfif>>SafeSerializeJSON()</option>
</select>
<input type="submit" value="SUBMIT" />
</form>
<hr />
<div>Links:</div>
<table border="1">
<thead>
<tr><th>URL:</th><th>Is Valid?</th><th>Use Custom Function?</th><th>DEC:</th><th>Output:</th></tr>
</thead>
<tbody>
#outputRow(8231,true,false)#
#outputRow(8232,false,false)#
#outputRow(8232,true,true)#
#outputRow(8233,false,false)#
#outputRow(8233,true,true)#
#outputRow(8234,true,false)#
#outputRow(9,true,false)#
#outputRow(10,true,false)#
#outputRow(11,true,false)#
#outputRow(33,true,false)#
#outputRow(34,true,false)#
#outputRow(49,true,false)#
#outputRow(50,true,false)#
#outputRow(51,true,false)#
#outputRow(97,true,false)#
#outputRow(98,true,false)#
#outputRow(99,true,false)#
</tbody>
</table>
</body>
</html></cfoutput>
<cffunction name="outputRow" output="true" access="private" returntype="void">
<cfargument name="chr" type="numeric" required="true" />
<cfargument name="valid" type="boolean" required="true" />
<cfargument name="useCustomFunction" type="boolean" required="true" />
<cfset var outputUrl = "json.cfm?useCustomFunction=#arguments.useCustomFunction#&chr=#arguments.chr#" />
<cfoutput>
<cfif arguments.valid><tr><cfelse><tr bgcolor="##cc0000"></cfif>
<td><a href="#outputUrl#">#outputUrl#</a>&nbsp;</td>
<td>#arguments.valid#&nbsp;</td>
<td>#arguments.useCustomFunction#&nbsp;</td>
<td>#arguments.chr#&nbsp;</td>
<td>#chr(arguments.chr)#&nbsp;</td>
</tr>
</cfoutput>
</cffunction>
<cffunction name="SafeSerializeJSON" output="false" access="private" returntype="string">
<cfargument name="obj" type="any" required="true" />
<cfargument name="serializeQueryByColumns" type="boolean" required="false" default="false" />
<cfset var jsonOutput = SerializeJSON(arguments.obj, arguments.serializeQueryByColumns) />
<cfset jsonOutput = Replace(jsonOutput, chr(8232), "\u2028", "all") />
<cfset jsonOutput = Replace(jsonOutput, chr(8233), "\u2029", "all") />
<cfreturn jsonOutput />
</cffunction>
<cfparam name="url.start" type="numeric" default="1" />
<cfparam name="url.end" type="numeric" default="1" />
<cfoutput><html>
<head>
<title>JSON Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div><a href="json2.cfm?start=1&end=1000">1-1000</a></div>
<div><a href="json2.cfm?start=1001&end=2000">1001-2000</a></div>
<div><a href="json2.cfm?start=2001&end=3000">2001-3000</a></div>
<div><a href="json2.cfm?start=3001&end=4000">3001-4000</a></div>
<div><a href="json2.cfm?start=4001&end=5000">4001-5000</a></div>
<div><a href="json2.cfm?start=5001&end=6000">5001-6000</a></div>
<div><a href="json2.cfm?start=6001&end=7000">6001-7000</a></div>
<div><a href="json2.cfm?start=7001&end=8000">7001-8000</a></div>
<div><a href="json2.cfm?start=8001&end=9000">8001-9000</a> <span style="color:##c00">Will cause errors at 8232 and 8233</span></div>
<div><a href="json2.cfm?start=9001&end=10000">9001-10000</a></div>
<div><a href="json2.cfm?start=10001&end=11000">10001-11000</a></div>
<div>Starting...</div>
<cfloop from="#url.start#" to="#Min(url.start+1000,url.end)#" index="i">
#outputRow(i)#
</cfloop>
<div>Finished...</div>
</body>
</html></cfoutput>
<cffunction name="outputRow" output="true" access="private" returntype="void">
<cfargument name="chr" type="numeric" required="true" />
<cfoutput>
<div id="jsOutput_#arguments.chr#"><span style="color:##c00">ERROR: #arguments.chr#</span></div>
<script type="text/javascript">
var myVar = #SerializeJSON("chr:" & chr(arguments.chr))#;
document.getElementById('jsOutput_#arguments.chr#').innerHTML = "";
</script>
</cfoutput>
</cffunction>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment