Here's my sample data, generated in my controller with
"db(...).select().as_list()":
====
events = [{'address': 'Poe Hall, Raleigh, NC 27607, USA',
'description': 'Description',
'food_desc': 'Food at the event',
'id': 15,
'latitude': '35.7855918',
'location': 'Room 9999',
'longitude': '-78.6663783',
'timestamp': '2010-12-17 11:44:58',
'title': 'Event title',
'university': 'North Carolina State University'},
{'address': 'Poe Hall, Raleigh, NC 27607, USA',
'description': "<script>alert('stuff');</script>",
'food_desc': 'Vulnerability stew',
'id': 16,
'latitude': '35.7855918',
'location': 'Room 9999',
'longitude': '-78.6663783',
'timestamp': '2010-12-17 11:44:58',
'title': 'XSS event',
'university': 'North Carolina State University'}]
====
I run this through "simplejson.dumps(data)", which produces this:
====
json_events = '[{"description": "Description", "title": "Event title",
"timestamp": "2010-12-17 11:44:58", "university": "North Carolina
State University", "longitude": "-78.6663783", "food_desc": "Food at
the event", "location": "Room 9999", "address": "Poe Hall, Raleigh, NC
27607, USA", "latitude": "35.7855918", "id": 15}, {"description":
"<script>alert(\'stuff\');</script>", "title": "XSS event",
"timestamp": "2010-12-17 11:44:58", "university": "North Carolina
State University", "longitude": "-78.6663783", "food_desc":
"Vulnerability stew", "location": "Room 9999", "address": "Poe Hall,
Raleigh, NC 27607, USA", "latitude": "35.7855918", "id": 16}]'
====
I pass that string into my view, where I want to use it like this:
====
...
<script type="text/javascript">
var events = {{=json_events}};
for(event in events) {
<do stuff with event["title"]>
<do stuff with event["description"]
...
}
</script>
...
====
However, this doesn't work because "{{=json_events}}" escapes the
quotes in the JSON string (producing "var events =
[{"description": "Description", ..."), so I
get a Javascript error saying "I don't know how to make sense of
'"', I need real quotes!".
I tried "{{response.write(json_events, escape=True}}" and
"{{=XML(json_events, sanitize=True}}", but those produce the same
Javascript error as the ordinary "{{=json_events}}".
So I tried "{{response.write(json_events, escape=False}}" and
"{{=XML(json_events, sanitize=False}}", but they leave the site
vulnerable to the Javascript embedded in the second event's
description.
So what I need is a way to escape/sanitize the data coming from the
database without escaping/sanitizing the quotation marks that allow me
to embed JSON in my view.
I have a temporary solution (using a loop with web2py view code to
print JSON into the view, element by element) but it's kludgy and a
pain to maintain. Is there a better solution to this dilemma?