Skip to content

Commit

Permalink
Merge template-comment-fix-5275
Browse files Browse the repository at this point in the history
Author: indigo
Reviewer: exarkun
Fixes: #5275

Add comment value mangling to `twisted.web.template` so that comments are not
emitted which will break an SGML-ish or XML parser on the receiving end.  Since
there is no real escaping rule for comments in an HTML document, the value is
mangled irreversibly.


git-svn-id: svn://svn.twistedmatrix.com/svn/Twisted/trunk@32678 bbbe8e31-12d6-0310-92fd-ac37d47ddeeb
  • Loading branch information
exarkun committed Sep 28, 2011
1 parent 2a8ad00 commit 478617a
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 5 deletions.
5 changes: 4 additions & 1 deletion twisted/web/_flatten.py
Expand Up @@ -75,7 +75,10 @@ def escapedComment(data):
"""
if isinstance(data, unicode):
data = data.encode('utf-8')
return data.replace('--', '- -')
data = data.replace('--', '- - ').replace('>', '>')
if data and data[-1] == '-':
data += ' '
return data


def _getSlotValue(name, slotData, default=None):
Expand Down
53 changes: 49 additions & 4 deletions twisted/web/test/test_flatten.py
Expand Up @@ -10,6 +10,7 @@
from twisted.trial.unittest import TestCase
from twisted.internet.defer import succeed, gatherResults
from twisted.web._stan import Tag
from twisted.web._flatten import flattenString
from twisted.web.error import UnfilledSlot, UnsupportedType, FlattenerError
from twisted.web.template import tags, Comment, CDATA, slot
from twisted.web.iweb import IRenderable
Expand Down Expand Up @@ -50,10 +51,54 @@ def test_serializeComment(self):
"""
Test that comments are correctly flattened and escaped.
"""
return gatherResults([
self.assertFlattensTo(Comment('foo bar'), '<!--foo bar-->'),
self.assertFlattensTo(Comment('foo -- bar'), '<!--foo - - bar-->'),
])
return self.assertFlattensTo(Comment('foo bar'), '<!--foo bar-->'),


def test_commentEscaping(self):
"""
The data in a L{Comment} is escaped and mangled in the flattened output
so that the result is a legal SGML and XML comment.
SGML comment syntax is complicated and hard to use. This rule is more
restrictive, and more compatible:
Comments start with <!-- and end with --> and never contain -- or >.
Also by XML syntax, a comment may not end with '-'.
@see: U{http://www.w3.org/TR/REC-xml/#sec-comments}
"""
def verifyComment(c):
self.assertTrue(
c.startswith('<!--'),
"%r does not start with the comment prefix" % (c,))
self.assertTrue(
c.endswith('-->'),
"%r does not end with the comment suffix" % (c,))
# If it is shorter than 7, then the prefix and suffix overlap
# illegally.
self.assertTrue(
len(c) >= 7,
"%r is too short to be a legal comment" % (c,))
content = c[4:-3]
self.assertNotIn('--', content)
self.assertNotIn('>', content)
if content:
self.assertNotEqual(content[-1], '-')

results = []
for c in [
'',
'foo---bar',
'foo---bar-',
'foo>bar',
'foo-->bar',
'----------------',
]:
d = flattenString(None, Comment(c))
d.addCallback(verifyComment)
results.append(d)
return gatherResults(results)


def test_serializeCDATA(self):
Expand Down
1 change: 1 addition & 0 deletions twisted/web/topfiles/5275.bugfix
@@ -0,0 +1 @@
twisted.web.template now escapes more inputs to comments which require escaping in the output.

0 comments on commit 478617a

Please sign in to comment.