Commits

Dan Villiom Podlaski Christiansen committed c9d923f

minirst: CGI escape strings prior to embedding it in the HTML

  • Participants
  • Parent commits 8aa053b

Comments (0)

Files changed (3)

File mercurial/minirst.py

 import util, encoding
 from i18n import _
 
+import cgi
+
 def section(s):
     return "%s\n%s\n\n" % (s, "\"" * encoding.colwidth(s))
 
     headernest = ''
     listnest = []
 
+    def escape(s):
+        return cgi.escape(s, True)
+
     def openlist(start, level):
         if not listnest or listnest[-1][0] != start:
             listnest.append((start, level))
         lines = b['lines']
 
         if btype == 'admonition':
-            admonition = _admonitiontitles[b['admonitiontitle']]
-            text = ' '.join(map(str.strip, lines))
+            admonition = escape(_admonitiontitles[b['admonitiontitle']])
+            text = escape(' '.join(map(str.strip, lines)))
             out.append('<p>\n<b>%s</b> %s\n</p>\n' % (admonition, text))
         elif btype == 'paragraph':
-            out.append('<p>\n%s\n</p>\n' % '\n'.join(lines))
+            out.append('<p>\n%s\n</p>\n' % escape('\n'.join(lines)))
         elif btype == 'margin':
             pass
         elif btype == 'literal':
-            out.append('<pre>\n%s\n</pre>\n' % '\n'.join(lines))
+            out.append('<pre>\n%s\n</pre>\n' % escape('\n'.join(lines)))
         elif btype == 'section':
             i = b['underline']
             if i not in headernest:
                 headernest += i
             level = headernest.index(i) + 1
-            out.append('<h%d>%s</h%d>\n' % (level, lines[0], level))
+            out.append('<h%d>%s</h%d>\n' % (level, escape(lines[0]), level))
         elif btype == 'table':
             table = b['table']
             t = []
             for row in table:
                 l = []
-                for v in zip(row):
-                    l.append('<td>%s</td>' % v)
+                for v in row:
+                    l.append('<td>%s</td>' % escape(v))
                 t.append(' <tr>%s</tr>\n' % ''.join(l))
             out.append('<table>\n%s</table>\n' % ''.join(t))
         elif btype == 'definition':
             openlist('dl', level)
-            term = lines[0]
-            text = ' '.join(map(str.strip, lines[1:]))
+            term = escape(lines[0])
+            text = escape(' '.join(map(str.strip, lines[1:])))
             out.append(' <dt>%s\n <dd>%s\n' % (term, text))
         elif btype == 'bullet':
             bullet, head = lines[0].split(' ', 1)
                 openlist('ul', level)
             else:
                 openlist('ol', level)
-            out.append(' <li> %s\n' % ' '.join([head] + lines[1:]))
+            out.append(' <li> %s\n' % escape(' '.join([head] + lines[1:])))
         elif btype == 'field':
             openlist('dl', level)
-            key = b['key']
-            text = ' '.join(map(str.strip, lines))
+            key = escape(b['key'])
+            text = escape(' '.join(map(str.strip, lines)))
             out.append(' <dt>%s\n <dd>%s\n' % (key, text))
         elif btype == 'option':
             openlist('dl', level)
-            opt = b['optstr']
-            desc = ' '.join(map(str.strip, lines))
+            opt = escape(b['optstr'])
+            desc = escape(' '.join(map(str.strip, lines)))
             out.append(' <dt>%s\n <dd>%s\n' % (opt, desc))
 
         # close lists if indent level of next block is lower

File tests/test-help.t

   </p>
   <p>
   The files will be added to the repository at the next commit. To
-  undo an add before that, see "hg forget".
+  undo an add before that, see &quot;hg forget&quot;.
   </p>
   <p>
   If no names are given, add all files to the repository.
   </p>
   <p>
   This command schedules the files to be removed at the next commit.
-  To undo a remove before that, see "hg revert". To undo added
-  files, see "hg forget".
+  To undo a remove before that, see &quot;hg revert&quot;. To undo added
+  files, see &quot;hg forget&quot;.
   </p>
   <p>
   Returns 0 on success, 1 if any warnings encountered.
   Any other string is treated as a bookmark, tag, or branch name. A
   bookmark is a movable pointer to a revision. A tag is a permanent name
   associated with a revision. A branch name denotes the tipmost revision
-  of that branch. Bookmark, tag, and branch names must not contain the ":"
+  of that branch. Bookmark, tag, and branch names must not contain the &quot;:&quot;
   character.
   </p>
   <p>
-  The reserved name "tip" always identifies the most recent revision.
+  The reserved name &quot;tip&quot; always identifies the most recent revision.
   </p>
   <p>
-  The reserved name "null" indicates the null revision. This is the
+  The reserved name &quot;null&quot; indicates the null revision. This is the
   revision of an empty repository, and the parent of revision 0.
   </p>
   <p>
-  The reserved name "." indicates the working directory parent. If no
+  The reserved name &quot;.&quot; indicates the working directory parent. If no
   working directory is checked out, it is equivalent to null. If an
-  uncommitted merge is in progress, "." is the revision of the first
+  uncommitted merge is in progress, &quot;.&quot; is the revision of the first
   parent.
   </p>
   

File tests/test-minirst.py.out

 html format:
 ----------------------------------------------------------------------
 <p>
-Please see "hg add".
+Please see &quot;hg add&quot;.
 </p>
 ----------------------------------------------------------------------
 
 <h1>Title</h1>
 <h2>Section</h2>
 <h3>Subsection</h3>
-<h2>Markup: "foo" and "hg help"</h2>
+<h2>Markup: &quot;foo&quot; and &quot;hg help&quot;</h2>
 ----------------------------------------------------------------------
 
 == admonitions ==