Commits

Christian Boos committed 807578a

0.12.3dev: fix an unicode issue in the `[[Image]]` macro.

When given a project relative path (as in #10485), we shouldn't
produce an UTF-8 encoded `str` out of it, as this will trigger an
`UnicodeError` when mixed with `unicode` later on.

Modified all the Image macros to take some unicode input, to verify
the other code paths. Also removed the request parameters from the
image URL, in the `alt` and `title` attributes, to make them less
noisy.

Closes #10485.

  • Participants
  • Parent commits bbb02ca

Comments (0)

Files changed (2)

File trac/wiki/macros.py

 from trac.util.datefmt import format_date, from_utimestamp
 from trac.util.html import escape, find_element
 from trac.util.presentation import separated
-from trac.util.text import unicode_quote, unquote, to_unicode
+from trac.util.text import unicode_quote, to_unicode
 from trac.util.translation import _
 from trac.wiki.api import IWikiMacroProvider, WikiSystem, parse_args
 from trac.wiki.formatter import format_to_html, format_to_oneliner, \
         url = raw_url = desc = None
         attachment = None
         if (parts and parts[0] in ('http', 'https', 'ftp')): # absolute
-            raw_url = url = desc = filespec
+            raw_url = url = filespec
+            desc = url.rsplit('?')[0]
         elif filespec.startswith('//'):       # server-relative
-            raw_url = url = desc = filespec[1:]
+            raw_url = url = filespec[1:]
+            desc = url.rsplit('?')[0]
         elif filespec.startswith('/'):        # project-relative
-            # use href, but unquote to allow args (use default html escaping)
-            raw_url = url = desc = unquote(formatter.href(filespec))
+            params = ''
+            if '?' in filespec:
+                filespec, params = filespec.rsplit('?', 1)
+            url = formatter.href(filespec)
+            if params:
+                url += '?' + params
+            raw_url, desc = url, filespec
         elif len(parts) == 3:                 # realm:id:attachment-filename
             #                                 # or intertrac:realm:id 
             realm, id, filename = parts

File trac/wiki/tests/macros.py

+# -*- coding: utf-8 -*-
 from datetime import datetime
 import unittest
 
 
 # == [[Image]]
 
+# Note: using `« test »` string in the following tests for checking
+#       unicode robustness and whitespace support (first space is
+#       normal ASCII SPACE, second is Unicode NO-BREAK SPACE).
+
 IMAGE_MACRO_TEST_CASES = u"""
 ============================== source: Image, no other arguments
-[[Image(source:test.png)]]
+[[Image(source:« test ».png)]]
 ------------------------------
 <p>
-<a style="padding:0; border:none" href="/browser/test.png"><img src="/browser/test.png?format=raw" alt="source:test.png" title="source:test.png" /></a>
+<a style="padding:0; border:none" href="/browser/%C2%AB%20test%C2%A0%C2%BB.png"><img src="/browser/%C2%AB%20test%C2%A0%C2%BB.png?format=raw" alt="source:« test ».png" title="source:« test ».png" /></a>
 </p>
 ------------------------------
 [[Image(...)]]
 ============================== intertrac:source: Image, no other arguments
-[[Image(trac:source:/trunk/doc/images/bkgnd_pattern.png)]]
+[[Image(trac:source:/trunk/doc/images/bkgnd_pattern_« test ».png)]]
 ------------------------------
 <p>
-<a style="padding:0; border:none" href="http://trac.edgewall.org/intertrac/source%3A/trunk/doc/images/bkgnd_pattern.png"><img src="http://trac.edgewall.org/intertrac/source%3A/trunk/doc/images/bkgnd_pattern.png%3Fformat%3Draw" alt="source:/trunk/doc/images/bkgnd_pattern.png in Trac's Trac" title="source:/trunk/doc/images/bkgnd_pattern.png in Trac's Trac" /></a>
+<a style="padding:0; border:none" href="http://trac.edgewall.org/intertrac/source%3A/trunk/doc/images/bkgnd_pattern_%C2%AB%20test%C2%A0%C2%BB.png"><img src="http://trac.edgewall.org/intertrac/source%3A/trunk/doc/images/bkgnd_pattern_%C2%AB%20test%C2%A0%C2%BB.png%3Fformat%3Draw" alt="source:/trunk/doc/images/bkgnd_pattern_« test ».png in Trac's Trac" title="source:/trunk/doc/images/bkgnd_pattern_« test ».png in Trac's Trac" /></a>
 </p>
 ------------------------------
 [[Image(...)]]
 ============================== source: Image, nolink
-[[Image(source:test.png, nolink)]]
+[[Image(source:« test », nolink)]]
 ------------------------------
 <p>
-<img src="/browser/test.png?format=raw" alt="source:test.png" title="source:test.png" />
+<img src="/browser/%C2%AB%20test%C2%A0%C2%BB?format=raw" alt="source:« test »" title="source:« test »" />
 </p>
 ------------------------------
 ============================== source: Image, normal args
-[[Image(source:test.png, align=left, title=Test)]]
+[[Image(source:« test », align=left, title=Test)]]
 ------------------------------
 <p>
-<a style="padding:0; border:none" href="/browser/test.png"><img src="/browser/test.png?format=raw" alt="source:test.png" style="float:left" title="Test" /></a>
+<a style="padding:0; border:none" href="/browser/%C2%AB%20test%C2%A0%C2%BB"><img src="/browser/%C2%AB%20test%C2%A0%C2%BB?format=raw" alt="source:« test »" style="float:left" title="Test" /></a>
 </p>
 ------------------------------
 ============================== source: Image, size arg
-[[Image(source:test.png, 30%)]]
+[[Image(source:« test », 30%)]]
 ------------------------------
 <p>
-<a style="padding:0; border:none" href="/browser/test.png"><img width="30%" alt="source:test.png" title="source:test.png" src="/browser/test.png?format=raw" /></a>
+<a style="padding:0; border:none" href="/browser/%C2%AB%20test%C2%A0%C2%BB"><img width="30%" alt="source:« test »" title="source:« test »" src="/browser/%C2%AB%20test%C2%A0%C2%BB?format=raw" /></a>
 </p>
 ------------------------------
 ============================== source: Image, keyword alignment
-[[Image(source:test.png, right)]]
+[[Image(source:« test », right)]]
 ------------------------------
 <p>
-<a style="padding:0; border:none" href="/browser/test.png"><img src="/browser/test.png?format=raw" alt="source:test.png" style="float:right" title="source:test.png" /></a>
+<a style="padding:0; border:none" href="/browser/%C2%AB%20test%C2%A0%C2%BB"><img src="/browser/%C2%AB%20test%C2%A0%C2%BB?format=raw" alt="source:« test »" style="float:right" title="source:« test »" /></a>
 </p>
 ------------------------------
 ============================== http: Image, nolink
-[[Image(http://www.edgewall.com/gfx/shredder.png, nolink)]]
+[[Image(http://www.edgewall.com/gfx/shredder_« test ».png, nolink)]]
 ------------------------------
 <p>
-<img src="http://www.edgewall.com/gfx/shredder.png" alt="http://www.edgewall.com/gfx/shredder.png" title="http://www.edgewall.com/gfx/shredder.png" />
+<img src="http://www.edgewall.com/gfx/shredder_« test ».png" alt="http://www.edgewall.com/gfx/shredder_« test ».png" title="http://www.edgewall.com/gfx/shredder_« test ».png" />
 </p>
 ------------------------------
 ============================== http: Image, absolute, many ':'
-[[Image(http://chart.apis.google.com:80/chart?cht=p3&chd=s:hW&chs=250x100&chl=Hello|World, title=Google & Charting, link=)]]
+[[Image(http://chart.apis.google.com:80/chart?cht=p3&chd=s:hW&chs=250x100&chl=Héllo|Wôrld, title=Google & Charting, link=)]]
 ------------------------------
 <p>
-<img src="http://chart.apis.google.com:80/chart?cht=p3&amp;chd=s:hW&amp;chs=250x100&amp;chl=Hello|World" alt="http://chart.apis.google.com:80/chart?cht=p3&amp;chd=s:hW&amp;chs=250x100&amp;chl=Hello|World" title="Google &amp; Charting" />
+<img src="http://chart.apis.google.com:80/chart?cht=p3&amp;chd=s:hW&amp;chs=250x100&amp;chl=Héllo|Wôrld" alt="http://chart.apis.google.com:80/chart" title="Google &amp; Charting" />
 </p>
 ------------------------------
 ============================== // Image, server-relative
-[[Image(//browser/test.png?format=raw, link=)]]
+[[Image(//browser/« test »?format=raw, link=)]]
 ------------------------------
 <p>
-<img src="/browser/test.png?format=raw" alt="/browser/test.png?format=raw" title="/browser/test.png?format=raw" />
+<img src="/browser/« test »?format=raw" alt="/browser/« test »" title="/browser/« test »" />
 </p>
 ------------------------------
 ============================== / Image, project-relative, link to WikiStart
-[[Image(/browser/test.png?format=raw, link=wiki:WikiStart)]]
+[[Image(/browser/« test »?format=raw, link=wiki:WikiStart)]]
 ------------------------------
 <p>
-<a style="padding:0; border:none" href="/wiki/WikiStart"><img src="/browser/test.png?format=raw" alt="/browser/test.png?format=raw" title="/browser/test.png?format=raw" /></a>
+<a style="padding:0; border:none" href="/wiki/WikiStart"><img src="/browser/%C2%AB%20test%C2%A0%C2%BB?format=raw" alt="/browser/« test »" title="/browser/« test »" /></a>
 </p>
 ------------------------------
 """
 
+# Note: in the <img> src attribute above, the Unicode characters
+#       within the URI sometimes come out as %-encoded, sometimes raw
+#       (server-relative case). Both forms are valid (at least
+#       according to the W3C XHTML validator).
+
+
 
 # == [[TitleIndex]]