Edgewall Software

Opened 7 years ago

Closed 6 years ago

#12234 closed defect (fixed)

TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

Reported by: anonymous Owned by: Ryan J Ollos
Priority: normal Milestone: 1.0.12
Component: wiki system Version: 0.12.3
Severity: normal Keywords:
Cc: Branch:
Release Notes:

Avoid TypeError with server-relative link containing [ (e.g. [[//a ] ]]).

API Changes:
Internal Changes:


Internal Error occurred when I added follow strings in wiki pages.

[[//a ] ]]

Most recent call last:

File "/var/service/python-2.6.6/lib/python2.6/site-packages/trac/wiki/templates/wiki_edit.html", line 136, in <Expression u'wiki_to_html(context(page.resource), page.text)'>
  ${wiki_to_html(context(page.resource), page.text)}
File "/var/service/python-2.6.6/lib/python2.6/site-packages/trac/wiki/formatter.py", line 1501, in format_to_html
  return HtmlFormatter(env, context, wikidom).generate(escape_newlines)
File "/var/service/python-2.6.6/lib/python2.6/site-packages/trac/wiki/formatter.py", line 1456, in generate
File "/var/service/python-2.6.6/lib/python2.6/site-packages/trac/wiki/formatter.py", line 1243, in format
  result = re.sub(self.wikiparser.rules, self.replace, line)
File "/var/service/python-2.6.6/lib/python2.6/re.py", line 151, in sub
  return _compile(pattern, 0).sub(repl, string, count)
File "/var/service/python-2.6.6/lib/python2.6/site-packages/trac/wiki/formatter.py", line 1161, in replace
  replacement = self.handle_match(fullmatch)
File "/var/service/python-2.6.6/lib/python2.6/site-packages/trac/wiki/formatter.py", line 1157, in handle_match
  return internal_handler(match, fullmatch)
File "/var/service/python-2.6.6/lib/python2.6/site-packages/trac/wiki/formatter.py", line 709, in _macrolink_formatter
  return self._lhref_formatter(match, fullmatch)
File "/var/service/python-2.6.6/lib/python2.6/site-packages/trac/wiki/formatter.py", line 540, in _lhref_formatter
  return self._make_lhref_link(match, fullmatch, rel, ns, target, label)
File "/var/service/python-2.6.6/lib/python2.6/site-packages/trac/wiki/formatter.py", line 546, in _make_lhref_link
  label = ns + ':' + target   #  use `http://target`

System Information:

  • Trac 0.12.3.ja2
  • Babel 0.9.5
  • Genshi 0.6
  • Python 2.6.6 (r266:84292, Mar 1 2011, 20:55:51) [GCC 4.1.2 20080704 (Red Hat 4.1.2-48)]

We create the following patch as a provisional, and have applied it.

  • src/trac/wiki/formatter.py

    diff --git a/src/trac/wiki/formatter.py b/src/trac/wiki/formatter.py
    index 6495550..442b35f 100644
    a b class Formatter(object):  
    542542    def _make_lhref_link(self, match, fullmatch, rel, ns, target, label):
    543543        if not label: # e.g. `[http://target]` or `[wiki:target]`
    544544            if target:
    545                 if target.startswith('//'):     # for `[http://target]`
     545                if ns and target.startswith('//'):     # for `[http://target]`
    546546                    label = ns + ':' + target   #  use `http://target`
    547547                else:                           # for `wiki:target`
    548548                    label = target.lstrip('/')  #  use only `target`

Attachments (0)

Change History (8)

comment:1 by Jun Omae, 7 years ago


Thanks for the reporting! Reproduced with Trac 0.12.7 and 1.0.9.

comment:2 by Ryan J Ollos, 6 years ago

Owner: set to Ryan J Ollos
Status: newassigned

comment:3 by Ryan J Ollos, 6 years ago

It's a pretty strange edge case. I'm not very familiar with the formatter.py code though, so maybe someone else could review before I commit.

  • trac/wiki/formatter.py

    616616    def _make_lhref_link(self, match, fullmatch, rel, ns, target, label):
    617617        if not label: # e.g. `[http://target]` or `[wiki:target]`
    618618            if target:
    619                 if target.startswith('//'):     # for `[http://target]`
     619                if ns and target.startswith('//'):     # for `[http://target]`
    620620                    label = ns + ':' + target   #  use `http://target`
    621621                else:                           # for `wiki:target`
    622622                    label = target.lstrip('/')  #  use only `target`
  • trac/wiki/tests/wiki-tests.txt

    363363[[../parent|See above]] Note: see wikisyntax tests for other parent tests
    364364[[./sibling|See next]]
    365365[[...|nothing to see]] [[...]]
     366[[//a ] ]]
    366367[[//docs|See documentation]]
    367368[[//images/logo.png|Our logo]]
    376377<a class="missing wiki" href="/wiki/parent" rel="nofollow">See above?</a> Note: see wikisyntax tests for other parent tests
    377378<a class="missing wiki" href="/wiki/WikiStart/sibling" rel="nofollow">See next?</a>
    378379<a class="missing wiki" href="/wiki/..." rel="nofollow">nothing to see?</a> <a class="missing wiki" href="/wiki/..." rel="nofollow">...?</a>
     380<a class="missing wiki" href="/wiki/a%20%5D%20" rel="nofollow">a ] ?</a>
    379381<a href="/docs">See documentation</a>
    380382<a href="/images/logo.png">Our logo</a>
    381383<a href="/">/</a>

comment:4 by Peter Suter, 6 years ago

My (possibly wrong) understanding is:

  • _make_lhref_link is only used by _lhref_formatter.
  • _lhref_formatter is the internal_handler for the lhref post-rule.
  • But _lhref_formatter is also used as a fallback by _macrolink_formatter (the internal handler for the macrolink post-rule) with _creolelink_re.
  • The lhref (long-hand reference?) handling is for [...] links.
    • Here a scheme: (ns) is required. [WikiStart] is not valid and not matched by the lhref post-rule.
  • The macrolink fallback / creole link handling is for [[...]] links.
    • Here a scheme: (ns) is optional. [[WikiStart]] is valid and matched by _creolelink_re.

In _make_lhref_link this is ignored. Even the comments there imply [...] (where ns is required) is the only handled scenario.

Now how should [[//a ] ]] be handled? I don't know.

  • [[a b ]] links a wiki page a b , similar to [[WikiStart]].
  • [[/a b ]] links project-relative server/project/a b , similar to [[/search]].
  • [[//a b ]] links server-relative server/a b , similar to [[//demo-1.1]].

But _lhref_relative_target does not match //a ] (or /a ] ) as a possible relative target due to the ], so:

  • [[a ] ]] still links a wiki page a ] .
  • [[/a ] ]] does not link to project-relative server/project/a ] , but instead again links to the wiki page a ] . Is that useful?
  • [[//a ] ]] does not link to server-relative server/a ] . With the proposed fix it would also again link to the wiki page a ] . Is that useful?

Maybe _lhref_relative_target is wrong to reject ]?

(OT: The documentation on server-relative links are slightly confusing. [/newticket] is not the same as [[//newticket]], e.g. on demo-1.1 [[//newticket]] points to t.e.o.! [/newticket] is the same as [[/newticket]], and [//newticket] is the same as [[//newticket]].)

Version 0, edited 6 years ago by Peter Suter (next)

comment:5 by Ryan J Ollos, 6 years ago


comment:6 by Ryan J Ollos, 6 years ago


in reply to:  4 comment:7 by Ryan J Ollos, 6 years ago

Replying to psuter:

But I think the proposed fix is good in the sense that it is an improvement, and somewhat consistent with already existing fallbacks for other strange links.

Thanks for the detailed look. For now I'll just push the change that prevents the TypeError. I guess it would be good to sort out the inconsistencies you mentioned, but I can't imagine I'll ever have a need to create a wiki page containing ] or even [...], so I'll wait to see if someone complains before looking further into those issues.

comment:8 by Ryan J Ollos, 6 years ago

Release Notes: modified (diff)
Resolution: fixed
Status: assignedclosed

Committed to 1.0-stable in [14772], merged to trunk in [14773].

Modify Ticket

Change Properties
Set your email in Preferences
as closed The owner will remain Ryan J Ollos.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from Ryan J Ollos to the specified user.

Add Comment

E-mail address and name can be saved in the Preferences .
Note: See TracTickets for help on using tickets.