Edgewall Software

Changeset 2724


Ignore:
Timestamp:
01/04/06 17:45:18 (5 years ago)
Author:
cmlenz
Message:

Porting to 0.9-stable:

Location:
branches/0.9-stable
Files:
1 added
62 edited

Legend:

Unmodified
Added
Removed
  • branches/0.9-stable/trac/About.py

    r2713 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2004-2006 Edgewall Software 
     
    2424from trac.perm import IPermissionRequestor 
    2525from trac.web import IRequestHandler 
     26from trac.util import Markup 
    2627from trac.web.chrome import add_stylesheet, INavigationContributor 
    2728 
     
    140141 
    141142    def get_navigation_items(self, req): 
    142         yield 'metanav', 'about', '<a href="%s" accesskey="9">About Trac</a>' \ 
    143               % self.env.href.about() 
     143        yield ('metanav', 'about', 
     144               Markup('<a href="%s">About Trac</a>', self.env.href.about())) 
    144145 
    145146    # IPermissionRequestor methods 
  • branches/0.9-stable/trac/Notify.py

    r2697 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
     
    1515# Author: Daniel Lundin <daniel@edgewall.com> 
    1616 
    17 from trac.__init__ import __version__ 
     17from trac import __version__ 
    1818from trac.core import TracError 
    1919from trac.util import CRLF, wrap 
     
    170170                                          subsequent_indent=' ', linesep=CRLF) 
    171171        self.ticket['link'] = self.env.abs_href.ticket(ticket.id) 
    172         self.hdf['email.ticket_props'] = self.format_props() 
    173         self.hdf['email.ticket_body_hdr'] = self.format_hdr() 
    174         self.hdf['ticket'] = self.ticket.values 
     172        self.hdf.set_unescaped('email.ticket_props', self.format_props()) 
     173        self.hdf.set_unescaped('email.ticket_body_hdr', self.format_hdr()) 
     174        self.hdf.set_unescaped('ticket', self.ticket.values) 
    175175        self.hdf['ticket.new'] = self.newticket 
    176176        subject = self.format_subj() 
    177177        if not self.newticket: 
    178178            subject = 'Re: ' + subject 
    179         self.hdf['email.subject'] = subject 
     179        self.hdf.set_unescaped('email.subject', subject) 
    180180        changes = '' 
    181181        if not self.newticket and modtime:  # Ticket change 
    182182            changelog = ticket.get_changelog(modtime) 
    183183            for date, author, field, old, new in changelog: 
    184                 self.hdf['ticket.change.author'] = author 
     184                self.hdf.set_unescaped('ticket.change.author', author) 
    185185                pfx = 'ticket.change.%s' % field 
    186186                newv = '' 
     
    194194                    cdescr += 'Old description:' + 2*CRLF + old_descr + 2*CRLF 
    195195                    cdescr += 'New description:' + 2*CRLF + new_descr + CRLF 
    196                     self.hdf['email.changes_descr'] = cdescr 
     196                    self.hdf.set_unescaped('email.changes_descr', cdescr) 
    197197                else: 
    198198                    newv = new 
     
    202202                    changes += '  * %s:  %s%s' % (field, chg, CRLF) 
    203203                if newv: 
    204                     self.hdf['%s.oldvalue' % pfx] = old 
    205                     self.hdf['%s.newvalue' % pfx] = newv 
     204                    self.hdf.set_unescaped('%s.oldvalue' % pfx, old) 
     205                    self.hdf.set_unescaped('%s.newvalue' % pfx, newv) 
    206206                if field == 'cc': 
    207207                    self.prev_cc += old and self.parse_cc(old) or [] 
    208                 self.hdf['%s.author' % pfx] = author 
     208                self.hdf.set_unescaped('%s.author' % pfx, author) 
    209209            if changes: 
    210                 self.hdf['email.changes_body'] = changes 
     210                self.hdf.set_unescaped('email.changes_body', changes) 
    211211        NotifyEmail.notify(self, ticket.id, subject) 
    212212 
  • branches/0.9-stable/trac/Search.py

    r2606 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2004 Edgewall Software 
     
    2121from trac.core import * 
    2222from trac.perm import IPermissionRequestor 
    23 from trac.util import TracError, escape, format_datetime 
     23from trac.util import TracError, escape, format_datetime, Markup 
    2424from trac.web import IRequestHandler 
    2525from trac.web.chrome import add_link, add_stylesheet, INavigationContributor 
     
    108108        if not req.perm.has_permission('SEARCH_VIEW'): 
    109109            return 
    110         yield 'mainnav', 'search', '<a href="%s" accesskey="4">Search</a>' \ 
    111               % (self.env.href.search()) 
     110        yield ('mainnav', 'search', 
     111               Markup('<a href="%s" accesskey="4">Search</a>', 
     112                      self.env.href.search())) 
    112113 
    113114    # IPermissionRequestor methods 
     
    178179                                                 q=query, page=page - 1) 
    179180                add_link(req, 'prev', prev_href, 'Previous Page') 
    180             req.hdf['search.page_href'] = escape( 
    181                 self.env.href.search(zip(filters, ['on'] * len(filters)), 
    182                                      q=query)) 
     181            req.hdf['search.page_href'] = self.env.href.search(zip(filters, ['on'] * len(filters)), q=query) 
    183182            req.hdf['search.result'] = [ 
    184                 { 'href': escape(result[0]), 
     183                { 'href': result[0], 
    185184                  'title': result[1], 
    186185                  'date': format_datetime(result[2]), 
    187                   'author': escape(result[3]), 
     186                  'author': result[3], 
    188187                  'excerpt': result[4] 
    189188                } for result in results] 
     
    238237    def _format_link(self, formatter, ns, query, label): 
    239238        if query and query[0] == '?': 
    240             href = formatter.href.search() + \ 
    241                    query.replace('&amp;', '&').replace(' ', '+') 
     239            href = formatter.href.search() + query.replace(' ', '+') 
    242240        else: 
    243241            href = formatter.href.search(q=query) 
  • branches/0.9-stable/trac/Settings.py

    r2127 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2004-2005 Edgewall Software 
     
    1818 
    1919from trac.core import * 
    20 from trac.util import escape 
     20from trac.util import Markup 
    2121from trac.web import IRequestHandler 
    2222from trac.web.chrome import INavigationContributor 
     23 
    2324 
    2425class SettingsModule(Component): 
     
    3435 
    3536    def get_navigation_items(self, req): 
    36         yield 'metanav', 'settings', '<a href="%s">Settings</a>' \ 
    37               % escape(self.env.href.settings()) 
     37        yield ('metanav', 'settings', 
     38               Markup('<a href="%s">Settings</a>', self.env.href.settings())) 
    3839 
    3940    # IRequestHandler methods 
  • branches/0.9-stable/trac/Timeline.py

    r2413 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
     
    2323from trac.core import * 
    2424from trac.perm import IPermissionRequestor 
    25 from trac.util import enum, escape, format_date, format_time, http_date 
     25from trac.util import enum, format_date, format_time, http_date, Markup 
    2626from trac.web import IRequestHandler 
    2727from trac.web.chrome import add_link, add_stylesheet, INavigationContributor 
     
    7171        if not req.perm.has_permission('TIMELINE_VIEW'): 
    7272            return 
    73         yield 'mainnav', 'timeline', '<a href="%s" accesskey="2">Timeline</a>' \ 
    74                                      % self.env.href.timeline() 
     73        yield ('mainnav', 'timeline', 
     74               Markup('<a href="%s" accesskey="2">Timeline</a>', 
     75                      self.env.href.timeline())) 
    7576 
    7677    # IPermissionRequestor methods 
     
    151152        idx = 0 
    152153        for kind, href, title, date, author, message in events: 
    153             event = {'kind': kind, 'title': title, 'href': escape(href), 
    154                      'author': escape(author or 'anonymous'), 
     154            event = {'kind': kind, 'title': title, 'href': href, 
     155                     'author': author or 'anonymous', 
    155156                     'date': format_date(date), 
    156157                     'time': format_time(date, '%H:%M'), 
     
    159160            if format == 'rss': 
    160161                # Strip/escape HTML markup 
    161                 event['title'] = re.sub(r'</?\w+(?: .*?)?>', '', title) 
    162                 event['message'] = escape(message) 
     162                if isinstance(title, Markup): 
     163                    event['title'] = title.striptags() 
     164                else: 
     165                    event['title'] = title 
    163166 
    164167                if author: 
    165168                    # For RSS, author must be an email address 
    166169                    if author.find('@') != -1: 
    167                         event['author.email'] = escape(author) 
     170                        event['author.email'] = author 
    168171                    elif email_map.has_key(author): 
    169                         event['author.email'] = escape(email_map[author]) 
     172                        event['author.email'] = email_map[author] 
    170173                event['date'] = http_date(date) 
    171174 
  • branches/0.9-stable/trac/__init__.py

    r2713 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22""" 
    33Trac 
  • branches/0.9-stable/trac/attachment.py

    r2659 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
     
    198198        'filename': attachment.filename, 
    199199        'description': wiki_to_oneliner(attachment.description, env, db), 
    200         'author': util.escape(attachment.author), 
     200        'author': attachment.author, 
    201201        'ipnr': attachment.ipnr, 
    202202        'size': util.pretty_size(attachment.size), 
     
    386386        req.perm.assert_permission(perm_map[attachment.parent_type]) 
    387387 
    388         fmt = req.args.get('format') 
    389         mimetype = fmt == 'txt' and 'text/plain' or \ 
    390                    get_mimetype(attachment.filename) or 'application/octet-stream' 
    391  
    392388        req.check_modified(attachment.time) 
    393389 
     
    403399        } 
    404400 
    405         raw_href = attachment.href(format='raw') 
    406         add_link(req, 'alternate', raw_href, 'Original Format', mimetype) 
    407         req.hdf['attachment.raw_href'] = raw_href 
    408  
    409401        perm_map = {'ticket': 'TICKET_ADMIN', 'wiki': 'WIKI_DELETE'} 
    410402        if req.perm.has_permission(perm_map[attachment.parent_type]): 
    411403            req.hdf['attachment.can_delete'] = 1 
    412404 
    413         self.log.debug("Rendering preview of file %s with mime-type %s" 
    414                        % (attachment.filename, mimetype)) 
    415405        fd = attachment.open() 
    416406        try: 
    417407            mimeview = Mimeview(self.env) 
    418  
    419408            max_preview_size = mimeview.max_preview_size() 
    420409            data = fd.read(max_preview_size) 
    421              
    422             if fmt in ('raw', 'txt'): 
    423                 # Send raw file 
    424                 charset = mimeview.preview_charset(data) 
    425                 req.send_file(attachment.path, mimetype + ';charset=' + charset) 
    426                 return 
    427              
    428             if not is_binary(data): 
     410 
     411            mime_type = get_mimetype(attachment.filename) or \ 
     412                        'application/octet-stream' 
     413            self.log.debug("Rendering preview of file %s with mime-type %s" 
     414                           % (attachment.filename, mime_type)) 
     415 
     416            raw_href = attachment.href(format='raw') 
     417            add_link(req, 'alternate', raw_href, 'Original Format', mime_type) 
     418            req.hdf['attachment.raw_href'] = raw_href 
     419 
     420            format = req.args.get('format') 
     421            render_unsafe = self.config.getbool('attachment', 
     422                                                'render_unsafe_content') 
     423            binary = not detect_unicode(data) and is_binary(data) 
     424 
     425            if format in ('raw', 'txt'): # Send raw file 
     426                if not render_unsafe and not binary: 
     427                    # Force browser to download HTML/SVG/etc pages that may 
     428                    # contain malicious code enabling XSS attacks 
     429                    req.send_header('Content-Disposition', 'attachment;' + 
     430                                    'filename=' + attachment.filename) 
     431                charset = mimeview.get_charset(data, mime_type) 
     432                if render_unsafe and not binary and format == 'txt': 
     433                    mime_type = 'text/plain' 
     434                req.send_file(attachment.path, 
     435                              mime_type + ';charset=' + charset) 
     436 
     437            if render_unsafe and not binary: 
    429438                add_link(req, 'alternate', attachment.href(format='txt'), 
    430                          'Plain Text', mimetype) 
    431  
    432             hdf = mimeview.preview_to_hdf(req, mimetype, None, data, 
     439                         'Plain Text', mime_type) 
     440 
     441            hdf = mimeview.preview_to_hdf(req, mime_type, None, data, 
    433442                                          attachment.filename, None, 
    434443                                          annotations=['lineno']) 
  • branches/0.9-stable/trac/config.py

    r2697 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
     
    5050 
    5151    def getbool(self, section, name, default=None): 
     52        """Return the specified option as boolean value. 
     53         
     54        If the value of the option is one of "yes", "true",  "on", or "1", this 
     55        method wll return `True`, otherwise `False`. 
     56         
     57        (since Trac 0.9.3) 
     58        """ 
    5259        if isinstance(default, basestring): 
    5360            default = default.lower() 
  • branches/0.9-stable/trac/core.py

    r2359 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
  • branches/0.9-stable/trac/db_default.py

    r2429 r2724  
    416416  ('header_logo', 'height', '73'), 
    417417  ('attachment', 'max_size', '262144'), 
     418  ('attachment', 'render_unsafe_content', 'false'), 
    418419  ('mimeviewer', 'enscript_path', 'enscript'), 
    419420  ('mimeviewer', 'php_path', 'php'), 
  • branches/0.9-stable/trac/env.py

    r2353 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
  • branches/0.9-stable/trac/loader.py

    r2532 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
  • branches/0.9-stable/trac/log.py

    r2127 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
  • branches/0.9-stable/trac/mimeview/api.py

    r2696 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2004-2005 Edgewall Software 
     
    2626 
    2727from trac.core import * 
    28 from trac.util import enum, escape, to_utf8 
     28from trac.util import enum, escape, to_utf8, Markup 
    2929 
    3030__all__ = ['get_charset', 'get_mimetype', 'is_binary', 'detect_unicode', 
     
    236236                    continue 
    237237                elif isinstance(result, (str, unicode)): 
    238                     return result 
     238                    return Markup(result) 
    239239                elif annotations: 
    240                     return self._annotate(result, annotations) 
     240                    return Markup(self._annotate(result, annotations)) 
    241241                else: 
    242242                    buf = StringIO() 
     
    245245                        buf.write(line + '\n') 
    246246                    buf.write('</pre></div>') 
    247                     return buf.getvalue() 
     247                    return Markup(buf.getvalue()) 
    248248            except Exception, e: 
    249249                self.log.warning('HTML preview using %s failed (%s)' 
     
    287287        return int(self.config.get('mimeviewer', 'max_preview_size', '262144')) 
    288288 
    289     def preview_charset(self, content): 
    290         return detect_unicode(content) or self.config.get('trac', 
    291                                                           'default_charset') 
     289    def get_charset(self, content='', mimetype=None): 
     290        """Infer the character encoding from the `content` or the `mimetype`. 
     291 
     292        The charset information in the `mimetype`, if given, 
     293        takes precedence over auto-detection. 
     294        Return the configured `default_charset` if no other information 
     295        is available. 
     296         
     297        (since Trac 0.9.3) 
     298        """ 
     299        if mimetype: 
     300            ctpos = mimetype.find('charset=') 
     301            if ctpos >= 0: 
     302                return mimetype[ctpos + 8:].strip() 
     303        return detect_unicode(content) or \ 
     304               self.config.get('trac', 'default_charset') 
    292305 
    293306    def preview_to_hdf(self, req, mimetype, charset, content, filename, 
  • branches/0.9-stable/trac/mimeview/enscript.py

    r2169 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2004-2005 Edgewall Software 
  • branches/0.9-stable/trac/mimeview/patch.py

    r2456 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
  • branches/0.9-stable/trac/mimeview/php.py

    r2127 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
  • branches/0.9-stable/trac/mimeview/rst.py

    r2127 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2004-2005 Edgewall Software 
  • branches/0.9-stable/trac/mimeview/silvercity.py

    r2345 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2004 Edgewall Software 
  • branches/0.9-stable/trac/mimeview/txtl.py

    r2720 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2004-2006 Edgewall Software 
  • branches/0.9-stable/trac/perm.py

    r2239 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
  • branches/0.9-stable/trac/test.py

    r2127 r2724  
    11#!/usr/bin/env python 
    2 # -*- coding: iso8859-1 -*- 
     2# -*- coding: iso-8859-1 -*- 
    33# 
    44# Copyright (C) 2003-2005 Edgewall Software 
  • branches/0.9-stable/trac/tests/__init__.py

    r2380 r2724  
    11import unittest 
    22 
    3 from trac.tests import attachment, config, core, db, env, perm 
     3from trac.tests import attachment, config, core, db, env, perm, util 
    44 
    55def suite(): 
     
    1111    suite.addTest(env.suite()) 
    1212    suite.addTest(perm.suite()) 
     13    suite.addTest(util.suite()) 
    1314    return suite 
    1415 
  • branches/0.9-stable/trac/tests/config.py

    r2697 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
  • branches/0.9-stable/trac/tests/core.py

    r2127 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
  • branches/0.9-stable/trac/ticket/api.py

    r2697 r2724  
    11# -*- coding: iso-8859-1 -*- 
    22# 
    3 # Copyright (C) 2003-2005 Edgewall Software 
     3# Copyright (C) 2003-2006 Edgewall Software 
    44# Copyright (C) 2003-2005 Jonas Borgström <jonas@edgewall.com> 
    55# All rights reserved. 
     
    141141 
    142142    def get_wiki_syntax(self): 
    143         yield (r"!?#\d+", 
     143        yield (r"(?:\A|[^&])#\d+", # #123 but not &#123; (HTML entity) 
    144144               lambda x, y, z: self._format_link(x, 'ticket', y[1:], y)) 
    145145 
     
    179179        for summary,desc,author,keywords,tid,date in cursor: 
    180180            yield (self.env.href.ticket(tid), 
    181                    '#%d: %s' % (tid, util.escape(util.shorten_line(summary))), 
     181                   '#%d: %s' % (tid, util.shorten_line(summary)), 
    182182                   date, author, 
    183                    util.escape(shorten_result(desc, query.split()))) 
     183                   shorten_result(desc, query.split())) 
    184184             
  • branches/0.9-stable/trac/ticket/model.py

    r2597 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003, 2004, 2005 Edgewall Software 
  • branches/0.9-stable/trac/ticket/query.py

    r2697 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2004-2005 Edgewall Software 
     
    341341        if req.perm.has_permission('TICKET_VIEW') and \ 
    342342           not self.env.is_component_enabled(ReportModule): 
    343             yield 'mainnav', 'tickets', '<a href="%s">View Tickets</a>' \ 
    344                   % escape(self.env.href.query()) 
     343            yield 'mainnav', 'tickets', Markup('<a href="%s">View Tickets</a>', 
     344                                               self.env.href.query()) 
    345345 
    346346    # IRequestHandler methods 
     
    503503                                   **query.constraints) 
    504504        req.hdf['query.order'] = query.order 
    505         req.hdf['query.href'] = escape(href) 
     505        req.hdf['query.href'] = href 
    506506        if query.desc: 
    507507            req.hdf['query.desc'] = True 
     
    553553            for field, value in ticket.items(): 
    554554                if field == 'time': 
    555                     ticket[field] = escape(format_datetime(value)) 
     555                    ticket[field] = format_datetime(value) 
    556556                elif field == 'description': 
    557557                    ticket[field] = wiki_to_html(value or '', self.env, req, db) 
    558558                else: 
    559                     ticket[field] = escape(value) 
     559                    ticket[field] = value 
    560560 
    561561        req.hdf['query.results'] = tickets 
     
    593593                result['reporter'] = '' 
    594594            if result['description']: 
    595                 result['description'] = escape(wiki_to_html(result['description'] or '', 
    596                                                             self.env, req, db, 
    597                                                             absurls=1)) 
     595                # str() cancels out the Markup() returned by wiki_to_html 
     596                result['description'] = str(wiki_to_html(result['description'] or '', 
     597                                                         self.env, req, db, 
     598                                                         absurls=1)) 
    598599            if result['time']: 
    599600                result['time'] = http_date(result['time']) 
     
    611612        if query[0] == '?': 
    612613            return '<a class="query" href="%s">%s</a>' \ 
    613                    % (escape(formatter.href.query()) + query.replace(' ', '+'), 
     614                   % (escape(formatter.href.query() + query.replace(' ', '+')), 
    614615                      label) 
    615616        else: 
    616617            from trac.ticket.query import Query, QuerySyntaxError 
    617618            try: 
    618                 query = Query.from_string(formatter.env, unescape(query)) 
     619                query = Query.from_string(formatter.env, query) 
    619620                return '<a class="query" href="%s">%s</a>' \ 
    620621                       % (escape(query.get_href()), label) 
  • branches/0.9-stable/trac/ticket/report.py

    r2322 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
     
    7474        if not req.perm.has_permission('REPORT_VIEW'): 
    7575            return 
    76         yield 'mainnav', 'tickets', '<a href="%s">View Tickets</a>' \ 
    77               % util.escape(self.env.href.report()) 
     76        yield ('mainnav', 'tickets', 
     77               util.Markup('<a href="%s">View Tickets</a>', 
     78                           self.env.href.report())) 
    7879 
    7980    # IPermissionRequestor methods   
     
    198199            'id': id, 
    199200            'mode': 'delete', 
    200             'title': util.escape(row[0]), 
     201            'title': util.row[0], 
    201202            'href': self.env.href.report(id) 
    202203        } 
     
    233234        req.hdf['report.id'] = id 
    234235        req.hdf['report.mode'] = 'edit' 
    235         req.hdf['report.title'] = util.escape(title) 
    236         req.hdf['report.sql'] = util.escape(sql) 
    237         req.hdf['report.description'] = util.escape(description) 
     236        req.hdf['report.title'] = title 
     237        req.hdf['report.sql'] = sql 
     238        req.hdf['report.description'] = description 
    238239 
    239240    def _render_view(self, req, db, id): 
     
    348349                    value['parsed'] = wiki_to_html(cell, self.env, req, db) 
    349350                elif column == 'reporter' and cell.find('@') != -1: 
    350                     value['rss'] = util.escape(cell) 
     351                    value['rss'] = cell 
    351352                elif column == 'report': 
    352353                    value['report_href'] = self.env.href.report(cell) 
     
    357358                    value['gmt'] = util.http_date(cell) 
    358359                prefix = 'report.items.%d.%s' % (row_idx, str(column)) 
    359                 req.hdf[prefix] = util.escape(str(cell)) 
     360                req.hdf[prefix] = str(cell) 
    360361                for key in value.keys(): 
    361362                    req.hdf[prefix + '.' + key] = value[key] 
     
    491492                    nodename = 'report.items.%s.%s' % (item.name(), col) 
    492493                    value = req.hdf.get(nodename, '') 
    493                     req.hdf[nodename] = util.escape(value) 
     494                    req.hdf[nodename] = value 
    494495                item = item.next() 
    495496 
  • branches/0.9-stable/trac/ticket/roadmap.py

    r2600 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2004-2005 Edgewall Software 
     
    2222from trac.core import * 
    2323from trac.perm import IPermissionRequestor 
    24 from trac.util import enum, escape, format_date, format_datetime, \ 
    25                       parse_date, pretty_timedelta, shorten_line, unescape, CRLF 
     24from trac.util import enum, escape, format_date, format_datetime, parse_date, \ 
     25                      pretty_timedelta, shorten_line, unescape, CRLF, Markup 
    2626from trac.ticket import Milestone, Ticket, TicketSystem 
    2727from trac.Timeline import ITimelineEventProvider 
     
    2929from trac.web.chrome import add_link, add_stylesheet, INavigationContributor 
    3030from trac.wiki import wiki_to_html, wiki_to_oneliner, IWikiSyntaxProvider 
     31 
    3132 
    3233def get_tickets_for_milestone(env, db, milestone, field='component'): 
     
    8889    if milestone.exists: 
    8990        safe_name = milestone.name.replace('/', '%2F') 
    90     hdf = {'name': escape(milestone.name), 
    91            'href': escape(env.href.milestone(safe_name))} 
     91    hdf = {'name': milestone.name, 
     92           'href': env.href.milestone(safe_name)} 
    9293    if milestone.description: 
    93         hdf['description_source'] = escape(milestone.description) 
     94        hdf['description_source'] = milestone.description 
    9495        hdf['description'] = wiki_to_html(milestone.description, env, req, db) 
    9596    if milestone.due: 
     
    129130        if not req.perm.has_permission('ROADMAP_VIEW'): 
    130131            return 
    131         yield 'mainnav', 'roadmap', '<a href="%s" accesskey="3">Roadmap</a>' \ 
    132                                     % self.env.href.roadmap() 
     132        yield ('mainnav', 'roadmap', 
     133               Markup('<a href="%s" accesskey="3">Roadmap</a>', 
     134                      self.env.href.roadmap())) 
    133135 
    134136    # IPermissionRequestor methods 
     
    163165            req.hdf[prefix + 'stats'] = calc_ticket_stats(tickets) 
    164166            for k, v in get_query_links(self.env, milestone_name).items(): 
    165                 req.hdf[prefix + 'queries.' + k] = escape(v) 
     167                req.hdf[prefix + 'queries.' + k] = v 
    166168            milestone['tickets'] = tickets # for the iCalendar view 
    167169 
     
    313315                           "WHERE completed>=%s AND completed<=%s", 
    314316                           (start, stop,)) 
    315             for completed,name,description in cursor: 
    316                 title = 'Milestone <em>%s</em> completed' % escape(name) 
     317            for completed, name, description in cursor: 
     318                title = Markup('Milestone <em>%s</em> completed', name) 
    317319                if format == 'rss': 
    318320                    href = self.env.abs_href.milestone(name) 
     
    471473        req.hdf['milestone.stats'] = stats 
    472474        for key, value in get_query_links(self.env, milestone.name).items(): 
    473             req.hdf['milestone.queries.' + key] = escape(value) 
     475            req.hdf['milestone.queries.' + key] = value 
    474476 
    475477        groups = _get_groups(self.env, db, by) 
     
    492494            for key, value in get_query_links(self.env, milestone.name, 
    493495                                              by, group).items(): 
    494                 req.hdf['%s.queries.%s' % (prefix, key)] = escape(value) 
     496                req.hdf['%s.queries.%s' % (prefix, key)] = value 
    495497            group_no += 1 
    496498        req.hdf['milestone.stats.max_percent_total'] = max_percent_total * 100 
  • branches/0.9-stable/trac/ticket/web_ui.py

    r2697 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
     
    3131from trac.wiki import wiki_to_html, wiki_to_oneliner 
    3232 
    33  
    3433class NewticketModule(Component): 
    3534 
     
    6766        if not req.perm.has_permission('TICKET_CREATE'): 
    6867            return 
    69         yield 'mainnav', 'newticket', \ 
    70               '<a href="%s" accesskey="7">New Ticket</a>' \ 
    71               % (self.env.href.newticket()) 
     68        yield ('mainnav', 'newticket',  
     69               util.Markup('<a href="%s" accesskey="7">New Ticket</a>', 
     70                           self.env.href.newticket())) 
    7271 
    7372    # IRequestHandler methods 
     
    9392 
    9493        req.hdf['title'] = 'New Ticket' 
    95         req.hdf['newticket'] = dict(zip(ticket.values.keys(), 
    96                                         [util.escape(value) for value 
    97                                          in ticket.values.values()])) 
     94        req.hdf['newticket'] = ticket.values 
    9895 
    9996        field_names = [field['name'] for field in ticket.fields 
     
    124121                    if milestone.is_completed: 
    125122                        options.remove(option) 
    126                 field['options'] = [util.escape(option) for option in options] 
     123                field['options'] = options 
    127124            req.hdf['newticket.fields.' + name] = field 
    128125 
     
    202199                comment = req.args.get('comment') 
    203200                if comment: 
    204                     req.hdf['ticket.comment'] = util.escape(comment) 
     201                    req.hdf['ticket.comment'] = comment 
    205202                    # Wiki format a preview of comment 
    206203                    req.hdf['ticket.comment_preview'] = wiki_to_html(comment, 
     
    283280            for t, id, resolution, status, type, message, author, summary \ 
    284281                    in cursor: 
    285                 title = 'Ticket <em title="%s">#%s</em> (%s) %s by %s' % ( 
    286                         util.escape(summary), id, type, verbs[status], 
    287                         util.escape(author)) 
     282                title = util.Markup('Ticket <em title="%s">#%s</em> (%s) %s by ' 
     283                                    '%s', summary, id, type, verbs[status], 
     284                                    author) 
    288285                if format == 'rss': 
    289286                    href = self.env.abs_href.ticket(id) 
     
    296293                    href = self.env.href.ticket(id) 
    297294                    if status != 'new': 
    298                         message = ': '.join(filter(None, [ 
     295                        message = util.Markup(': ').join(filter(None, [ 
    299296                            resolution, 
    300297                            wiki_to_oneliner(message, self.env, db, 
     
    303300                    else: 
    304301                        message = util.escape(util.shorten_line(message)) 
    305                 yield kinds[status], href, title, t, author, message 
     302                yield kinds[status], href, title, t, author 
    306303 
    307304    # Internal methods 
     
    362359    def _insert_ticket_data(self, req, db, ticket, reporter_id): 
    363360        """Insert ticket data into the hdf""" 
    364         req.hdf['ticket'] = dict(zip(ticket.values.keys(), 
    365                                  map(lambda x: util.escape(x), 
    366                                      ticket.values.values()))) 
     361        req.hdf['ticket'] = ticket.values 
    367362        req.hdf['ticket.id'] = ticket.id 
    368363        req.hdf['ticket.href'] = self.env.href.ticket(ticket.id) 
     
    376371                    # possible values 
    377372                    options.append(value) 
    378                 field['options'] = [util.escape(option) for option in options] 
     373                field['options'] = options 
    379374            name = field['name'] 
    380375            del field['name'] 
     
    384379            req.hdf['ticket.fields.' + name] = field 
    385380 
    386         req.hdf['ticket.reporter_id'] = util.escape(reporter_id) 
    387         req.hdf['title'] = '#%d (%s)' % (ticket.id, 
    388                                          util.escape(ticket['summary'])) 
     381        req.hdf['ticket.reporter_id'] = reporter_id 
     382        req.hdf['title'] = '#%d (%s)' % (ticket.id, ticket['summary']) 
    389383        req.hdf['ticket.description.formatted'] = wiki_to_html(ticket['description'], 
    390384                                                               self.env, req, db) 
     
    404398                changes.append({ 
    405399                    'date': util.format_datetime(date), 
    406                     'author': util.escape(author), 
     400                    'author': author, 
    407401                    'fields': {} 
    408402                }) 
     
    414408                changes[-1]['fields'][field] = '' 
    415409            else: 
    416                 changes[-1]['fields'][field] = {'old': util.escape(old), 
    417                                                 'new': util.escape(new)} 
     410                changes[-1]['fields'][field] = {'old': old, 
     411                                                'new': new} 
    418412        req.hdf['ticket.changes'] = changes 
    419413 
     
    482476                else: 
    483477                    href = self.env.href.ticket(id)  
    484                 title = 'Ticket <em title="%s">#%s</em> (%s) updated by %s' \ 
    485                         % (util.escape(summary), id, type, util.escape(author)) 
    486                 message = '' 
     478                title = util.Markup('Ticket <em title="%s">#%s</em> (%s) ' 
     479                                    'updated by %s', summary, id, type, author) 
     480                message = util.Markup() 
    487481                if len(field_changes) > 0: 
    488                     message = ', '.join(field_changes) + ' changed.<br />' 
     482                    message = util.Markup(', ').join(field_changes) + \ 
     483                              ' changed.<br />' 
    489484                message += wiki_to_oneliner(comment, self.env, db, 
    490485                                            shorten=True, absurls=absurls) 
  • branches/0.9-stable/trac/util.py

    r2606 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2004 Edgewall Software 
     
    1515# Author: Jonas Borgström <jonas@edgewall.com> 
    1616 
    17 from __future__ import generators 
    18  
     17import cgi 
     18import md5 
    1919import os 
     20import re 
     21try: 
     22    frozenset 
     23except NameError: 
     24    from sets import ImmutableSet as frozenset 
    2025import sys 
    2126import time 
    2227import tempfile 
    23 import re 
    24 import md5 
    2528 
    2629TRUE =  ['yes', '1', 1, 'true',  'on',  'aye'] 
     
    3942        idx += 1 
    4043 
    41 def escape(text, quotes=True): 
     44 
     45class Markup(str): 
     46    """Marks a string as being safe for inclusion in XML output without needing 
     47    to be escaped. 
     48     
     49    Strings are normally automatically escaped when added to the HDF. 
     50    `Markup`-strings are however an exception. Use with care. 
     51     
     52    (since Trac 0.9.3) 
    4253    """ 
    43     Escapes &, <, > and \" so they are safe to include in HTML output. Quotes 
    44     are only escaped if the `quotes` parameter is `True`; this is only 
    45     necessary for text that is supposed to be inserted in attributes of HTML 
    46     tags. 
    47     """ 
    48     if not text: 
    49         return '' 
    50     text = str(text).replace('&', '&amp;') \ 
    51                     .replace('<', '&lt;') \ 
    52                     .replace('>', '&gt;') 
    53     if quotes: 
    54         text = text.replace('"', '&#34;') 
    55     return text 
     54    def __new__(self, text='', *args): 
     55        if args: 
     56            text %= tuple([escape(arg) for arg in args]) 
     57        return str.__new__(self, text) 
     58 
     59    def __add__(self, other): 
     60        return Markup(str(self) + Markup.escape(other)) 
     61 
     62    def __mul__(self, num): 
     63        return Markup(str(self) * num) 
     64 
     65    def join(self, seq): 
     66        return Markup(str(self).join([Markup.escape(item) for item in seq])) 
     67 
     68    def striptags(self): 
     69        """Return a copy of the text with all XML/HTML tags removed.""" 
     70        return Markup(re.sub(r'<[^>]*?>', '', self)) 
     71 
     72    def escape(cls, text, quotes=True): 
     73        """Create a Markup instance from a string and escape special characters 
     74        it may contain (<, >, & and "). 
     75         
     76        If the `quotes` parameter is set to `False`, the " character is left as 
     77        is. Escaping quotes is generally only required for strings that are to 
     78        be used in attribute values. 
     79        """ 
     80        if isinstance(text, cls): 
     81            return text 
     82        if not text: 
     83            return cls() 
     84        text = str(text).replace('&', '&amp;') \ 
     85                        .replace('<', '&lt;') \ 
     86                        .replace('>', '&gt;') 
     87        if quotes: 
     88            text = text.replace('"', '&#34;') 
     89        return cls(text) 
     90    escape = classmethod(escape) 
     91 
     92    def unescape(self): 
     93        """Reverse-escapes &, <, > and " and returns a `str`.""" 
     94        if not self: 
     95            return '' 
     96        return str(self).replace('&#34;', '"') \ 
     97                        .replace('&gt;', '>') \ 
     98                        .replace('&lt;', '<') \ 
     99                        .replace('&amp;', '&') 
     100 
     101    def sanitize(self): 
     102        """Parse the text as HTML and return a cleaned up XHTML representation. 
     103         
     104        This will remove any javascript code or other potentially dangerous 
     105        elements. 
     106         
     107        If the HTML cannot be parsed, an `HTMLParseError` will be raised by the 
     108        underlying `HTMLParser` module, which should be handled by the caller of 
     109        this function. 
     110        """ 
     111        import htmlentitydefs 
     112        from HTMLParser import HTMLParser, HTMLParseError 
     113        from StringIO import StringIO 
     114 
     115        buf = StringIO() 
     116 
     117        class HTMLSanitizer(HTMLParser): 
     118            # FIXME: move this out into a top-level class 
     119            safe_tags = frozenset(['a', 'abbr', 'acronym', 'address', 'area', 
     120                'b', 'big', 'blockquote', 'br', 'button', 'caption', 'center', 
     121                'cite', 'code', 'col', 'colgroup', 'dd', 'del', 'dfn', 'dir', 
     122                'div', 'dl', 'dt', 'em', 'fieldset', 'font', 'form', 'h1', 'h2', 
     123                'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'input', 'ins', 'kbd', 
     124                'label', 'legend', 'li', 'map', 'menu', 'ol', 'optgroup', 
     125                'option', 'p', 'pre', 'q', 's', 'samp', 'select', 'small', 
     126                'span', 'strike', 'strong', 'sub', 'sup', 'table', 'tbody', 
     127                'td', 'textarea', 'tfoot', 'th', 'thead', 'tr', 'tt', 'u', 'ul', 
     128                'var']) 
     129            safe_attrs = frozenset(['abbr', 'accept', 'accept-charset', 
     130                'accesskey', 'action', 'align', 'alt', 'axis', 'border', 
     131                'cellpadding', 'cellspacing', 'char', 'charoff', 'charset', 
     132                'checked', 'cite', 'class', 'clear', 'cols', 'colspan', 'color', 
     133                'compact', 'coords', 'datetime', 'dir', 'disabled', 'enctype', 
     134                'for', 'frame', 'headers', 'height', 'href', 'hreflang', 
     135                'hspace', 'id', 'ismap', 'label', 'lang', 'longdesc', 
     136                'maxlength', 'media', 'method', 'multiple', 'name', 'nohref', 
     137                'noshade', 'nowrap', 'prompt', 'readonly', 'rel', 'rev', 'rows', 
     138                'rowspan', 'rules', 'scope', 'selected', 'shape', 'size', 
     139                'span', 'src', 'start', 'style', 'summary', 'tabindex', 
     140                'target', 'title', 'type', 'usemap', 'valign', 'value', 
     141                'vspace', 'width']) 
     142            uri_attrs = frozenset(['action', 'background', 'dynsrc', 'href', 
     143                                  'lowsrc', 'src']) 
     144            safe_schemes = frozenset(['file', 'ftp', 'http', 'https', 'mailto', 
     145                                      None]) 
     146            empty_tags = frozenset(['br', 'hr', 'img', 'input']) 
     147            waiting_for = None 
     148 
     149            def handle_starttag(self, tag, attrs): 
     150                if self.waiting_for: 
     151                    return 
     152                if tag not in self.safe_tags: 
     153                    self.waiting_for = tag 
     154                    return 
     155                buf.write('<' + tag) 
     156 
     157                def _get_scheme(text): 
     158                    if ':' not in text: 
     159                        return None 
     160                    chars = [char for char in text.split(':', 1)[0] 
     161                             if char.isalnum()] 
     162                    return ''.join(chars).lower() 
     163 
     164                for attrname, attrval in attrs: 
     165                    if attrname not in self.safe_attrs: 
     166                        continue 
     167                    elif attrname in self.uri_attrs: 
     168                        # Don't allow URI schemes such as "javascript:" 
     169                        if _get_scheme(attrval) not in self.safe_schemes: 
     170                            continue 
     171                    elif attrname == 'style': 
     172                        # Remove dangerous CSS declarations from inline styles 
     173                        decls = [] 
     174                        for decl in filter(None, attrval.split(';')): 
     175                            is_evil = False 
     176                            if 'expression' in decl: 
     177                                is_evil = True 
     178                            for m in re.finditer(r'url\s*\(([^)]+)', decl): 
     179                                if _get_scheme(m.group(1)) not in self.safe_schemes: 
     180                                    is_evil = True 
     181                                    break 
     182                            if not is_evil: 
     183                                decls.append(decl.strip()) 
     184                        if not decls: 
     185                            continue 
     186                        attrval = '; '.join(decls) 
     187                    buf.write(' ' + attrname + '="' + escape(attrval) + '"') 
     188 
     189                if tag in self.empty_tags: 
     190                    buf.write(' />') 
     191                else: 
     192                    buf.write('>') 
     193 
     194            def handle_entityref(self, name): 
     195                if not self.waiting_for: 
     196                    if name not in ('amp', 'lt', 'gt', 'quot'): 
     197                        codepoint = htmlentitydefs.name2codepoint[name] 
     198                        buf.write(unichr(codepoint).encode('utf-8')) 
     199                    else: 
     200                        buf.write('&%s;' % name) 
     201 
     202            def handle_data(self, data): 
     203                if not self.waiting_for: 
     204                    buf.write(escape(data, quotes=False)) 
     205 
     206            def handle_endtag(self, tag): 
     207                if self.waiting_for: 
     208                    if self.waiting_for == tag: 
     209                        self.waiting_for = None 
     210                    return 
     211                if tag not in self.empty_tags: 
     212                    buf.write('</' + tag + '>') 
     213 
     214        # Translate any character or entity references to the corresponding 
     215        # UTF-8 characters 
     216        def _ref2utf8(match): 
     217            ref = match.group(1) 
     218            if ref.startswith('x'): 
     219                ref = int(ref[1:], 16) 
     220            else: 
     221                ref = int(ref, 10) 
     222            return unichr(int(ref)).encode('utf-8') 
     223        text = re.sub(r'&#((?:\d+)|(?:[xX][0-9a-fA-F]+));?', _ref2utf8, self) 
     224 
     225        sanitizer = HTMLSanitizer() 
     226        sanitizer.feed(text) 
     227        return Markup(buf.getvalue()) 
     228 
     229 
     230escape = Markup.escape 
    56231 
    57232def unescape(text): 
    58     """ 
    59     Reverse-escapes &, <, > and \". 
    60     """ 
    61     if not text: 
    62         return '' 
    63     return str(text).replace('&#34;', '"') \ 
    64                     .replace('&gt;', '>') \ 
    65                     .replace('&lt;', '<') \ 
    66                     .replace('&amp;', '&')  
     233    """Reverse-escapes &, <, > and \".""" 
     234    if not isinstance(text, Markup): 
     235        return text 
     236    return text.unescape() 
    67237 
    68238def to_utf8(text, charset='iso-8859-15'): 
  • branches/0.9-stable/trac/versioncontrol/api.py

    r2315 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
  • branches/0.9-stable/trac/versioncontrol/cache.py

    r2709 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
  • branches/0.9-stable/trac/versioncontrol/diff.py

    r2381 r2724  
    1 # -*- coding: iso8859-1 -*- 
    2 # 
    3 # Copyright (C) 2004-2005 Edgewall Software 
    4 # Copyright (C) 2004-2005 Christopher Lenz <cmlenz@gmx.de> 
     1# -*- coding: iso-8859-1 -*- 
     2# 
     3# Copyright (C) 2004-2006 Edgewall Software 
     4# Copyright (C) 2004-2006 Christopher Lenz <cmlenz@gmx.de> 
    55# All rights reserved. 
    66# 
     
    1717from __future__ import generators 
    1818 
    19 from trac.util import enum, escape 
     19from trac.util import enum, escape, Markup 
    2020 
    2121from difflib import SequenceMatcher 
     
    189189                    line = line.expandtabs(tabwidth) 
    190190                    line = space_re.sub(htmlify, escape(line, quotes=False)) 
    191                     blocks[-1]['base.lines'].append(line) 
     191                    blocks[-1]['base.lines'].append(Markup(line)) 
    192192                for line in tolines[j1:j2]: 
    193193                    line = line.expandtabs(tabwidth) 
    194194                    line = space_re.sub(htmlify, escape(line, quotes=False)) 
    195                     blocks[-1]['changed.lines'].append(line) 
     195                    blocks[-1]['changed.lines'].append(Markup(line)) 
    196196            else: 
    197197                if tag in ('replace', 'delete'): 
     
    200200                        line = escape(line, quotes=False).replace('\0', '<del>') \ 
    201201                                                         .replace('\1', '</del>') 
    202                         blocks[-1]['base.lines'].append(space_re.sub(htmlify, 
    203                                                                      line)) 
     202                        blocks[-1]['base.lines'].append(Markup(space_re.sub(htmlify, 
     203                                                                            line))) 
    204204                if tag in ('replace', 'insert'): 
    205205                    for line in tolines[j1:j2]: 
     
    207207                        line = escape(line, quotes=False).replace('\0', '<ins>') \ 
    208208                                                         .replace('\1', '</ins>') 
    209                         blocks[-1]['changed.lines'].append(space_re.sub(htmlify, 
    210                                                                         line)) 
     209                        blocks[-1]['changed.lines'].append(Markup(space_re.sub(htmlify, 
     210                                                                               line))) 
    211211        changes.append(blocks) 
    212212    return changes 
  • branches/0.9-stable/trac/versioncontrol/svn_authz.py

    r2550 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2004-2005 Edgewall Software 
  • branches/0.9-stable/trac/versioncontrol/svn_fs.py

    r2710 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
  • branches/0.9-stable/trac/versioncontrol/tests/cache.py

    r2709 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
  • branches/0.9-stable/trac/versioncontrol/tests/svn_fs.py

    r2625 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
  • branches/0.9-stable/trac/versioncontrol/web_ui/browser.py

    r2569 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
     
    2727from trac.wiki import wiki_to_html, wiki_to_oneliner, IWikiSyntaxProvider 
    2828from trac.versioncontrol.web_ui.util import * 
     29 
    2930 
    3031IMG_RE = re.compile(r"\.(gif|jpg|jpeg|png)(\?.*)?$", re.IGNORECASE) 
     
    6263        if not req.perm.has_permission('BROWSER_VIEW'): 
    6364            return 
    64         yield 'mainnav', 'browser', '<a href="%s">Browse Source</a>' \ 
    65               % util.escape(self.env.href.browser()) 
     65        yield ('mainnav', 'browser', 
     66               util.Markup('<a href="%s">Browse Source</a>', 
     67                           self.env.href.browser())) 
    6668 
    6769    # IPermissionRequestor methods 
     
    98100            'path': path, 
    99101            'revision': rev or repos.youngest_rev, 
    100             'props': dict([(util.escape(name), util.escape(value)) 
     102            'props': dict([(name, value) 
    101103                           for name, value in node.get_properties().items() 
    102104                           if not name in hidden_properties]), 
    103             'href': util.escape(self.env.href.browser(path, rev=rev or 
    104                                                       repos.youngest_rev)), 
    105             'log_href': util.escape(self.env.href.log(path, rev=rev or None)) 
     105            'href': self.env.href.browser(path, rev=rev or 
     106                                          repos.youngest_rev), 
     107            'log_href': self.env.href.log(path, rev=rev or None) 
    106108        } 
    107109 
     
    141143                'rev': entry.rev, 
    142144                'permission': 1, # FIXME 
    143                 'log_href': util.escape(self.env.href.log(entry.path, rev=rev)), 
    144                 'browser_href': util.escape(self.env.href.browser(entry.path, 
    145                                                                   rev=rev)) 
     145                'log_href': self.env.href.log(entry.path, rev=rev), 
     146                'browser_href': self.env.href.browser(entry.path, 
     147                                                      rev=rev) 
    146148            }) 
    147149        changes = get_changes(self.env, repos, [i['rev'] for i in info]) 
     
    171173        req.hdf['file'] = {   
    172174            'rev': node.rev,   
    173             'changeset_href': util.escape(self.env.href.changeset(node.rev)), 
     175            'changeset_href': self.env.href.changeset(node.rev), 
    174176            'date': util.format_datetime(changeset.date), 
    175177            'age': util.pretty_timedelta(changeset.date), 
     
    223225            raw_href = self.env.href.browser(node.path, rev=rev and node.rev, 
    224226                                             format='raw') 
    225             req.hdf['file.raw_href'] = util.escape(raw_href) 
     227            req.hdf['file.raw_href'] = raw_href 
    226228            add_link(req, 'alternate', raw_href, 'Original Format', mime_type) 
    227229 
  • branches/0.9-stable/trac/versioncontrol/web_ui/changeset.py

    r2699 r2724  
    120120                    message = chgset.message or '--' 
    121121                    if format == 'rss': 
    122                         title = 'Changeset <em>[%s]</em>: %s' \ 
    123                                 % (util.escape(chgset.rev), 
    124                                    util.escape(util.shorten_line(message))) 
     122                        title = util.Markup('Changeset <em>[%s]</em>: %s', 
     123                                            chgset.rev, 
     124                                            util.shorten_line(message)) 
    125125                        href = self.env.abs_href.changeset(chgset.rev) 
    126126                        message = wiki_to_html(message, self.env, req, db, 
    127127                                               absurls=True) 
    128128                    else: 
    129                         title = 'Changeset <em>[%s]</em> by %s' \ 
    130                                 % (util.escape(chgset.rev), 
    131                                    util.escape(chgset.author)) 
     129                        title = util.Markup('Changeset <em>[%s]</em> by %s', 
     130                                            chgset.rev, chgset.author) 
    132131                        href = self.env.href.changeset(chgset.rev) 
    133132                        message = wiki_to_oneliner(message, self.env, db, 
     
    144143                                  '</span>: ' + message 
    145144                    yield 'changeset', href, title, chgset.date, chgset.author,\ 
    146                           message 
     145                          util.Markup(message) 
    147146                rev = repos.previous_rev(rev) 
    148147 
     
    155154            'revision': chgset.rev, 
    156155            'time': util.format_datetime(chgset.date), 
    157             'author': util.escape(chgset.author or 'anonymous'), 
     156            'author': chgset.author or 'anonymous', 
    158157            'message': wiki_to_html(chgset.message or '--', self.env, req, 
    159158                                    escape_newlines=True) 
     
    394393                continue 
    395394            yield (self.env.href.changeset(rev), 
    396                    '[%s]: %s' % (rev, util.escape(util.shorten_line(log))), 
    397                    date, author, 
    398                    util.escape(shorten_result(log, query.split()))) 
     395                   '[%s]: %s' % (rev, util.shorten_line(log)), 
     396                   date, author, shorten_result(log, query.split())) 
  • branches/0.9-stable/trac/versioncontrol/web_ui/log.py

    r2382 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
     
    159159                    email_map[username] = email 
    160160            for cs in changes.values(): 
    161                 cs['message'] = util.escape(cs['message']) 
    162                 cs['shortlog'] = util.escape(cs['shortlog'].replace('\n', ' ')) 
     161                cs['shortlog'] = cs['shortlog'].replace('\n', ' ') 
    163162                # For RSS, author must be an email address 
    164163                author = cs['author'] 
  • branches/0.9-stable/trac/versioncontrol/web_ui/util.py

    r2413 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
     
    1919 
    2020from trac.util import escape, format_datetime, pretty_timedelta, shorten_line, \ 
    21                       TracError 
     21                      TracError, Markup 
    2222from trac.wiki import wiki_to_html, wiki_to_oneliner 
    2323 
     
    6565        links.append({ 
    6666            'name': part or 'root', 
    67             'href': escape(href.browser(path, rev=rev)) 
     67            'href': href.browser(path, rev=rev) 
    6868        }) 
    6969    return links 
     
    8787        return repos.get_node(path, rev)  
    8888    except TracError, e:  
    89         raise TracError(e.message + '<br><p>You can <a href="%s">search</a> '  
    90                         'in the repository history to see if that path ' 
    91                         'existed but was later removed.</p>' 
    92                         % escape(env.href.log(path, rev=rev, 
    93                                               mode='path_history'))) 
     89        raise TracError(Markup('%s<br><p>You can <a href="%s">search</a> '  
     90                               'in the repository history to see if that path ' 
     91                               'existed but was later removed.</p>', e.message, 
     92                               env.href.log(path, rev=rev, 
     93                                            mode='path_history'))) 
  • branches/0.9-stable/trac/web/_fcgi.py

    r2130 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (c) 2002, 2003, 2005 Allan Saddi <allan@saddi.com> 
  • branches/0.9-stable/trac/web/api.py

    r2127 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
     
    188188        self.send_header('Content-Length', stat.st_size) 
    189189        self.send_header('Last-Modified', last_modified) 
     190        for name, value in self._headers: 
     191            self.send_header(name, value) 
    190192        self._send_cookie_headers() 
    191193        self.end_headers() 
  • branches/0.9-stable/trac/web/auth.py

    r2697 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
     
    2222from trac.web.api import IAuthenticator, IRequestHandler 
    2323from trac.web.chrome import INavigationContributor 
    24 from trac.util import escape, hex_entropy 
     24from trac.util import escape, hex_entropy, Markup 
    2525 
    2626 
     
    6464    def get_navigation_items(self, req): 
    6565        if req.authname and req.authname != 'anonymous': 
    66             yield 'metanav', 'login', 'logged in as %s' % escape(req.authname) 
    67             yield 'metanav', 'logout', '<a href="%s">Logout</a>' \ 
    68                   % escape(self.env.href.logout()) 
     66            yield ('metanav', 'login', 'logged in as %s' % req.authname) 
     67            yield ('metanav', 'logout', 
     68                   Markup('<a href="%s">Logout</a>'  
     69                          % escape(self.env.href.logout()))) 
    6970        else: 
    70             yield 'metanav', 'login', '<a href="%s">Login</a>' \ 
    71                   % escape(self.env.href.login()) 
     71            yield ('metanav', 'login', 
     72                   Markup('<a href="%s">Login</a>'  
     73                          % escape(self.env.href.login()))) 
    7274 
    7375    # IRequestHandler methods 
  • branches/0.9-stable/trac/web/cgi_frontend.py

    r2260 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
  • branches/0.9-stable/trac/web/chrome.py

    r2432 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
     
    2929    the <head> of the generated HTML 
    3030    """ 
    31     link = {'href': util.escape(href)} 
     31    link = {'href': href} 
    3232    if title: 
    33         link['title'] = util.escape(title) 
     33        link['title'] = title 
    3434    if mimetype: 
    3535        link['type'] = mimetype 
     
    236236                    logo_src = href.chrome('common', logo_src) 
    237237            req.hdf['chrome.logo'] = { 
    238                 'link': util.escape(logo_link), 'src': util.escape(logo_src), 
    239                 'src_abs': util.escape(logo_src_abs), 
    240                 'alt': util.escape(self.config.get('header_logo', 'alt')), 
     238                'link': logo_link, 'src': logo_src, 
     239                'src_abs': logo_src_abs, 
     240                'alt': self.config.get('header_logo', 'alt'), 
    241241                'width': self.config.get('header_logo', 'width', ''), 
    242242                'height': self.config.get('header_logo', 'height', '') 
    243243            } 
    244244        else: 
    245             req.hdf['chrome.logo.link'] = util.escape(logo_link) 
     245            req.hdf['chrome.logo.link'] = logo_link 
    246246 
    247247        # Navigation links 
  • branches/0.9-stable/trac/web/clearsilver.py

    r2127 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: utf-8 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
     
    1616 
    1717from trac.util import enum, TracError 
     18from trac import util 
    1819 
    1920 
     
    191192        KeyError: 'test.none' 
    192193        """ 
     194        self.set_value(name, value, True) 
     195         
     196    def set_unescaped(self, name, value): 
     197        """ 
     198        Add data to the HDF dataset. 
     199         
     200        This method works the same way as `__setitem__` except that `value` 
     201        is not escaped if it is a string. 
     202        """ 
     203        self.set_value(name, value, False) 
     204         
     205    def set_value(self, name, value, escape=True): 
     206        """ 
     207        Add data to the HDF dataset. 
     208        """ 
    193209        def add_value(prefix, value): 
    194210            if value is None: 
     
    196212            elif value in (True, False): 
    197213                self.hdf.setValue(prefix, str(int(value))) 
     214            elif isinstance(value, util.Markup): 
     215                self.hdf.setValue(prefix, value) 
    198216            elif isinstance(value, (str, unicode)): 
    199                 self.hdf.setValue(prefix, value) 
     217                if escape: 
     218                    self.hdf.setValue(prefix, util.escape(value)) 
     219                else: 
     220                    self.hdf.setValue(prefix, value) 
    200221            elif isinstance(value, dict): 
    201222                for k in value.keys(): 
  • branches/0.9-stable/trac/web/href.py

    r2218 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
  • branches/0.9-stable/trac/web/main.py

    r2417 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
     
    2222from trac.env import open_environment 
    2323from trac.perm import PermissionCache, PermissionError 
    24 from trac.util import escape, enum, format_datetime, http_date, to_utf8 
     24from trac.util import escape, enum, format_datetime, http_date, to_utf8, Markup 
    2525from trac.web.api import absolute_url, Request, RequestDone, IAuthenticator, \ 
    2626                         IRequestHandler 
     
    172172 
    173173    hdf['project'] = { 
    174         'name': env.config.get('project', 'name'), 
    175         'name_encoded': escape(env.config.get('project', 'name')), 
     174        'name': Markup(env.config.get('project', 'name')), 
     175        'name_encoded': env.config.get('project', 'name'), 
    176176        'descr': env.config.get('project', 'descr'), 
    177         'footer': env.config.get('project', 'footer', 
    178                  'Visit the Trac open source project at<br />' 
    179                  '<a href="http://trac.edgewall.com/">' 
    180                  'http://trac.edgewall.com/</a>'), 
     177        'footer': Markup(env.config.get('project', 'footer')), 
    181178        'url': env.config.get('project', 'url') 
    182179    } 
     
    186183        hdf['base_host'] = req.base_url[:req.base_url.rfind(req.cgi_location)] 
    187184        hdf['cgi_location'] = req.cgi_location 
    188         hdf['trac.authname'] = escape(req.authname) 
     185        hdf['trac.authname'] = req.authname 
    189186 
    190187        for action in req.perm.permissions(): 
     
    224221            req.hdf['error.message'] = e.message 
    225222            if e.show_traceback: 
    226                 req.hdf['error.traceback'] = escape(tb.getvalue()) 
     223                req.hdf['error.traceback'] = tb.getvalue() 
    227224            req.display('error.cs', response=500) 
    228225 
     
    237234            req.hdf['title'] = 'Oops' 
    238235            req.hdf['error.type'] = 'internal' 
    239             req.hdf['error.message'] = escape(str(e)) 
    240             req.hdf['error.traceback'] = escape(tb.getvalue()) 
     236            req.hdf['error.message'] = str(e) 
     237            req.hdf['error.traceback'] = tb.getvalue() 
    241238            req.display('error.cs', response=500) 
    242239 
  • branches/0.9-stable/trac/web/modpython_frontend.py

    r2266 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2004-2005 Edgewall Software 
  • branches/0.9-stable/trac/web/session.py

    r2127 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2004-2005 Edgewall Software 
  • branches/0.9-stable/trac/web/standalone.py

    r2531 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
     
    325325        Request.__init__(self) 
    326326        self.__handler = handler 
     327        self.__status_sent = False 
    327328 
    328329        self.scheme = 'http' 
     
    356357    def send_response(self, code): 
    357358        self.__handler.send_response(code) 
     359        self.__status_sent = True 
    358360 
    359361    def send_header(self, name, value): 
    360         self.__handler.send_header(name, value) 
     362        if not self.__status_sent: 
     363            self._headers.append((name, value)) 
     364        else: 
     365            self.__handler.send_header(name, value) 
    361366 
    362367    def end_headers(self): 
  • branches/0.9-stable/trac/web/tests/href.py

    r2127 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
  • branches/0.9-stable/trac/wiki/api.py

    r2697 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
  • branches/0.9-stable/trac/wiki/formatter.py

    r2657 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    3 # Copyright (C) 2003-2005 Edgewall Software 
     3# Copyright (C) 2003-2006 Edgewall Software 
    44# Copyright (C) 2003-2005 Jonas Borgström <jonas@edgewall.com> 
    55# Copyright (C) 2004-2005 Christopher Lenz <cmlenz@gmx.de> 
     6# Copyright (C) 2005-2006 Christian Boos <cboos@neuf.fr> 
    67# All rights reserved. 
    78# 
     
    3940 <pre>%s</pre> 
    4041</div> 
    41 """ % (msg, util.escape(text)) 
     42""" % (util.escape(msg), util.escape(text)) 
    4243 
    4344 
     
    8081 
    8182    def _html_processor(self, req, text): 
    82         if Formatter._htmlproc_disallow_rule.search(text): 
    83             err = system_message('Error: HTML block contains disallowed tags.', 
    84                                  text) 
    85             self.env.log.error(err) 
    86             return err 
    87         if Formatter._htmlproc_disallow_attribute.search(text): 
    88             err = system_message('Error: HTML block contains disallowed attributes.', 
    89                                  text) 
    90             self.env.log.error(err) 
    91             return err 
    92         return text 
     83        from HTMLParser import HTMLParseError 
     84        try: 
     85            return util.Markup(text).sanitize() 
     86        except HTMLParseError, e: 
     87            self.env.log.warn(e) 
     88            return system_message('HTML parsing error: %s' % util.escape(e.msg), 
     89                                  text.splitlines()[e.lineno - 1].strip()) 
    9390 
    9491    def _macro_processor(self, req, text): 
     
    106103    def process(self, req, text, inline=False): 
    107104        if self.error: 
    108             return system_message('Error: Failed to load processor <code>%s</code>' 
    109                                   % self.name, self.error) 
     105            return system_message(util.Markup('Error: Failed to load processor ' 
     106                                              '<code>%s</code>', self.name), 
     107                                  self.error) 
    110108        text = self.processor(req, text) 
    111109        if inline: 
     
    139137 
    140138    SHREF_TARGET_FIRST = r"[\w/?!#@]" 
    141     SHREF_TARGET_MIDDLE = r"(?:\|(?=[^|\s])|&(?!lt;|gt;)|[^|&\s])" 
     139    SHREF_TARGET_MIDDLE = r"(?:\|(?=[^|\s])|[^|<>\s])" 
    142140    SHREF_TARGET_LAST = r"[a-zA-Z0-9/=]" # we don't want "_" 
    143141 
     
    159157        r"(?P<inlinecode>!?\{\{\{(?P<inline>.*?)\}\}\})", 
    160158        r"(?P<inlinecode2>!?%s(?P<inline2>.*?)%s)" \ 
    161         % (INLINE_TOKEN, INLINE_TOKEN), 
    162         # Prevent HTML entities to be recognized as ticket shorthand links 
    163         r"(?P<htmlescapeentity>!?&#\d+;)"] 
     159        % (INLINE_TOKEN, INLINE_TOKEN)] 
    164160 
    165161    _post_rules = [ 
     162        r"(?P<htmlescape>[&<>])", 
    166163        # shref corresponds to short TracLinks, i.e. sns:stgt 
    167164        r"(?P<shref>!?((?P<sns>%s):(?P<stgt>%s|%s(?:%s*%s)?)))" \ 
     
    187184     
    188185    img_re = re.compile(r"\.(gif|jpg|jpeg|png)(\?.*)?$", re.IGNORECASE) 
    189     _htmlproc_disallow_rule = re.compile('(?i)<(script|noscript|embed|object|' 
    190                                          'iframe|frame|frameset|link|style|' 
    191                                          'meta|param|doctype)') 
    192     _htmlproc_disallow_attribute = re.compile('(?i)<[^>]*\s+(on\w+)=') 
    193186 
    194187    def __init__(self, env, req=None, absurls=0, db=None): 
     
    299292    def _make_link(self, ns, target, match, label): 
    300293        if ns in self.link_resolvers: 
    301             return self.link_resolvers[ns](self, ns, target, label) 
     294            return self.link_resolvers[ns](self, ns, target, 
     295                                           util.escape(label, False)) 
    302296        elif target.startswith('//') or ns == "mailto": 
    303297            return self._make_ext_link(ns+':'+target, label) 
    304298        else: 
    305             return match 
     299            return util.escape(match) 
    306300 
    307301    def _make_ext_link(self, url, text, title=''): 
     302        url = util.escape(url) 
     303        text, title = util.escape(text), util.escape(title) 
    308304        title_attr = title and ' title="%s"' % title or '' 
    309305        if Formatter.img_re.search(url) and self.flavor != 'oneliner': 
     
    316312 
    317313    def _make_relative_link(self, url, text): 
     314        url, text = util.escape(url), util.escape(text) 
    318315        if Formatter.img_re.search(url) and self.flavor != 'oneliner': 
    319316            return '<img src="%s" alt="%s" />' % (url, text) 
     
    360357        return '<tt>%s</tt>' % fullmatch.group('inline2') 
    361358 
    362     def _htmlescapeentity_formatter(self, match, fullmatch): 
    363         #dummy function that match html escape entities in the format: 
    364         # &#[0-9]+; 
    365         # This function is used to avoid these being matched by 
    366         # the tickethref regexp 
    367         return match 
     359    def _htmlescape_formatter(self, match, fullmatch): 
     360        return match == "&" and "&amp;" or match == "<" and "&lt;" or "&gt;" 
    368361 
    369362    def _macro_formatter(self, match, fullmatch): 
     
    372365            return '<br />' 
    373366        args = fullmatch.group('macroargs') 
    374         args = util.unescape(args) 
    375367        try: 
    376368            macro = WikiProcessor(self.env, name) 
     
    392384        heading = match[depth + 1:len(match) - depth - 1] 
    393385 
    394         text = wiki_to_oneliner(util.unescape(heading), self.env, self.db, 
    395                                 self._absurls) 
     386        text = wiki_to_oneliner(heading, self.env, self.db, self._absurls) 
    396387        sans_markup = re.sub(r'</?\w+(?: .*?)?>', '', text) 
    397388 
     
    602593                continue 
    603594 
    604             line = util.escape(line, False) 
    605595            if escape_newlines: 
    606596                line += ' [[BR]]' 
     
    645635    def _list_formatter(self, match, fullmatch): return match 
    646636    def _indent_formatter(self, match, fullmatch): return match 
    647     def _heading_formatter(self, match, fullmatch): return match 
    648     def _definition_formatter(self, match, fullmatch): return match 
     637    def _heading_formatter(self, match, fullmatch): 
     638        return util.escape(match, False) 
     639    def _definition_formatter(self, match, fullmatch): 
     640        return util.escape(match, False) 
    649641    def _table_cell_formatter(self, match, fullmatch): return match 
    650642    def _last_table_cell_formatter(self, match, fullmatch): return match 
     
    691683            result = util.shorten_line(result) 
    692684 
    693         result = re.sub(self.rules, self.replace, util.escape(result, False)) 
     685        result = re.sub(self.rules, self.replace, result) 
    694686        result = result.replace('[...]', '[&hellip;]') 
    695687        if result.endswith('...'): 
     
    743735        heading = match[depth + 1:len(match) - depth - 1] 
    744736        anchor = self._anchors[-1] 
    745         text = wiki_to_oneliner(util.unescape(heading), self.env, self.db, 
    746                                 self._absurls) 
     737        text = wiki_to_oneliner(heading, self.env, self.db, self._absurls) 
    747738        text = re.sub(r'</?a(?: .*?)?>', '', text) # Strip out link tags 
    748739        self.outline.append((depth, '<a href="#%s">%s</a>' % (anchor, text))) 
     
    752743    out = StringIO() 
    753744    Formatter(env, req, absurls, db).format(wikitext, out, escape_newlines) 
    754     return out.getvalue() 
     745    return util.Markup(out.getvalue()) 
    755746 
    756747def wiki_to_oneliner(wikitext, env, db=None, shorten=False, absurls=0): 
    757748    out = StringIO() 
    758749    OneLinerFormatter(env, absurls, db).format(wikitext, out, shorten) 
    759     return out.getvalue() 
     750    return util.Markup(out.getvalue()) 
    760751 
    761752def wiki_to_outline(wikitext, env, db=None, absurls=0, max_depth=None, 
     
    764755    OutlineFormatter(env, absurls, db).format(wikitext, out, max_depth, 
    765756                                              min_depth) 
    766     return out.getvalue() 
     757    return util.Markup(out.getvalue()) 
  • branches/0.9-stable/trac/wiki/macros.py

    r2717 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2005 Edgewall Software 
  • branches/0.9-stable/trac/wiki/model.py

    r2453 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22# 
    33# Copyright (C) 2003-2005 Edgewall Software 
  • branches/0.9-stable/trac/wiki/tests/wiki-tests.txt

    r2657 r2724  
    6666#1, [1], r1, {1} 
    6767============================== 
     68&#1; &#23; 
     69------------------------------ 
     70<p> 
     71&amp;#1; &amp;#23; 
     72</p> 
     73------------------------------ 
     74&amp;#1; &amp;#23; 
     75============================== 
    6876[1:2], r1:2, [12:23], r12:23 
    6977------------------------------ 
     
    116124This ticket is the first one 
    117125changeset:123> 
     126changeset:123& 
    118127------------------------------ 
    119128<p> 
     
    123132This ticket is the first one 
    124133<a class="missing changeset" href="/changeset/123" rel="nofollow">changeset:123</a>&gt; 
     134<a class="missing changeset" href="/changeset/123" rel="nofollow">changeset:123</a>&amp; 
    125135</p> 
    126136------------------------------ 
     
    130140This ticket is the first one 
    131141<a class="missing changeset" href="/changeset/123" rel="nofollow">changeset:123</a>&gt; 
     142<a class="missing changeset" href="/changeset/123" rel="nofollow">changeset:123</a>&amp; 
    132143============================== 
    133144CamelCase AlabamA ABc AlaBamA FooBar 
     
    477488}}} 
    478489------------------------------ 
    479 <div class="system-message"> 
    480  <strong>Error: HTML block contains disallowed tags.</strong> 
    481  <pre>&lt;script&gt;alert(&#34;&#34;);&lt;/script&gt; 
    482 </pre> 
    483 </div> 
     490 
    484491------------------------------ 
    485492 [&hellip;] 
     
    490497}}} 
    491498------------------------------ 
    492 <div class="system-message"> 
    493  <strong>Error: HTML block contains disallowed attributes.</strong> 
    494  <pre>&lt;div onclick=&#34;alert('')&#34;&gt;Click me&lt;/div&gt; 
    495 </pre> 
    496 </div> 
     499<div>Click me</div> 
    497500------------------------------ 
    498501 [&hellip;] 
     
    541544------------------------------ 
    542545<p> 
    543 Inline <B> Test </B> text 
     546Inline <b> Test </b> text 
    544547</p> 
    545548------------------------------ 
  • branches/0.9-stable/trac/wiki/web_ui.py

    r2606 r2724  
    2626from trac.Search import ISearchSource, query_to_sql, shorten_result 
    2727from trac.Timeline import ITimelineEventProvider 
    28 from trac.util import enum, escape, format_datetime, get_reporter_id, \ 
    29                       pretty_timedelta, shorten_line 
     28from trac.util import enum, format_datetime, get_reporter_id, \ 
     29                      pretty_timedelta, shorten_line, Markup 
    3030from trac.versioncontrol.diff import get_diff_options, hdf_diff 
    3131from trac.web.chrome import add_link, add_stylesheet, INavigationContributor 
     
    4848        if not req.perm.has_permission('WIKI_VIEW'): 
    4949            return 
    50         yield 'metanav', 'help', '<a href="%s" accesskey="6">Help/Guide</a>' \ 
    51               % escape(self.env.href.wiki('TracGuide')) 
    52         yield 'mainnav', 'wiki', '<a href="%s" accesskey="1">Wiki</a>' \ 
    53               % escape(self.env.href.wiki()) 
     50        yield ('metanav', 'help', 
     51               Markup('<a href="%s" accesskey="6">Help/Guide</a>', 
     52                      self.env.href.wiki('TracGuide'))) 
     53        yield ('mainnav', 'wiki', 
     54               Markup('<a href="%s" accesskey="1">Wiki</a>', 
     55                      self.env.href.wiki())) 
    5456 
    5557    # IPermissionRequestor methods 
     
    115117 
    116118        req.hdf['wiki.action'] = action 
    117         req.hdf['wiki.page_name'] = escape(page.name) 
    118         req.hdf['wiki.current_href'] = escape(self.env.href.wiki(page.name)) 
     119        req.hdf['wiki.page_name'] = page.name 
     120        req.hdf['wiki.current_href'] = self.env.href.wiki(page.name) 
    119121        return 'wiki.cs', None 
    120122 
     
    134136                           (start, stop)) 
    135137            for t,name,comment,author in cursor: 
    136                 title = '<em>%s</em> edited by %s' % ( 
    137                         escape(name), escape(author)) 
     138                title = Markup('<em>%s</em> edited by %s', name, author) 
    138139                if format == 'rss': 
    139140                    href = self.env.abs_href.wiki(name) 
     
    197198            version = int(req.args.get('version', 0)) 
    198199 
    199         req.hdf['title'] = escape(page.name) + ' (delete)' 
    200         req.hdf['wiki'] = {'page_name': escape(page.name), 'mode': 'delete'} 
     200        req.hdf['title'] = page.name + ' (delete)' 
     201        req.hdf['wiki'] = {'page_name': page.name, 'mode': 'delete'} 
    201202        if version is not None: 
    202203            req.hdf['wiki.version'] = version 
     
    217218        add_stylesheet(req, 'common/css/diff.css') 
    218219 
    219         req.hdf['title'] = escape(page.name) + ' (diff)' 
     220        req.hdf['title'] = page.name + ' (diff)' 
    220221 
    221222        # Ask web spiders to not index old versions 
     
    233234        info = { 
    234235            'version': page.version, 
    235             'history_href': escape(self.env.href.wiki(page.name, 
    236                                                       action='history')) 
     236            'history_href': self.env.href.wiki(page.name, action='history') 
    237237        } 
    238238 
     
    244244                    info['time'] = format_datetime(t) 
    245245                    info['time_delta'] = pretty_timedelta(t) 
    246                 info['author'] = escape(author or 'anonymous') 
    247                 info['comment'] = escape(comment or '--') 
    248                 info['ipnr'] = escape(ipnr or '') 
     246                info['author'] = author or 'anonymous' 
     247                info['comment'] = comment or '--' 
     248                info['ipnr'] = ipnr or '' 
    249249            else: 
    250250                num_changes += 1 
     
    294294            editrows = req.session.get('wiki_editrows', '20') 
    295295 
    296         req.hdf['title'] = escape(page.name) + ' (edit)' 
     296        req.hdf['title'] = page.name + ' (edit)' 
    297297        info = { 
    298298            'page_name': page.name, 
    299             'page_source': escape(page.text), 
     299            'page_source': page.text, 
    300300            'version': page.version, 
    301             'author': escape(author), 
    302             'comment': escape(comment), 
     301            'author': author, 
     302            'comment': comment, 
    303303            'readonly': page.readonly, 
    304304            'edit_rows': editrows, 
     
    306306        } 
    307307        if page.exists: 
    308             info['history_href'] = escape(self.env.href.wiki(page.name, 
    309                                                              action='history')) 
     308            info['history_href'] = self.env.href.wiki(page.name, 
     309                                                      action='history') 
    310310        if preview: 
    311311            info['page_html'] = wiki_to_html(page.text, self.env, req, db) 
     
    325325            raise TracError, "Page %s does not exist" % page.name 
    326326 
    327         req.hdf['title'] = escape(page.name) + ' (history)' 
     327        req.hdf['title'] = page.name + ' (history)' 
    328328 
    329329        history = [] 
    330330        for version, t, author, comment, ipnr in page.get_history(): 
    331331            history.append({ 
    332                 'url': escape(self.env.href.wiki(page.name, version=version)), 
    333                 'diff_url': escape(self.env.href.wiki(page.name, 
    334                                                       version=version, 
    335                                                       action='diff')), 
     332                'url': self.env.href.wiki(page.name, version=version), 
     333                'diff_url': self.env.href.wiki(page.name, 
     334                                               version=version, 
     335                                               action='diff'), 
    336336                'version': version, 
    337337                'time': format_datetime(t), 
    338338                'time_delta': pretty_timedelta(t), 
    339                 'author': escape(author), 
     339                'author': author, 
    340340                'comment': wiki_to_oneliner(comment or '', self.env, db), 
    341341                'ipaddr': ipnr 
     
    349349            req.hdf['title'] = '' 
    350350        else: 
    351             req.hdf['title'] = escape(page.name) 
     351            req.hdf['title'] = page.name 
    352352 
    353353        version = req.args.get('version') 
     
    364364            req.hdf['wiki.page_html'] = wiki_to_html(page.text, self.env, req) 
    365365            history_href = self.env.href.wiki(page.name, action='history') 
    366             req.hdf['wiki.history_href'] = escape(history_href) 
     366            req.hdf['wiki.history_href'] = history_href 
    367367        else: 
    368368            if not req.perm.has_permission('WIKI_CREATE'): 
    369369                raise TracError('Page %s not found' % page.name) 
    370             req.hdf['wiki.page_html'] = '<p>Describe "%s" here</p>' % page.name 
     370            req.hdf['wiki.page_html'] = Markup('<p>Describe "%s" here</p>', 
     371                                               page.name) 
    371372 
    372373        # Show attachments 
     
    400401        for name, date, author, text in cursor: 
    401402            yield (self.env.href.wiki(name), 
    402                    '%s: %s' % (name, escape(shorten_line(text))), 
     403                   '%s: %s' % (name, shorten_line(text)), 
    403404                   date, author, 
    404                    escape(shorten_result(text, query.split()))) 
     405                   shorten_result(text, query.split())) 
  • branches/0.9-stable/wiki-macros/TracGuideToc.py

    r2435 r2724  
    1 # -*- coding: iso8859-1 -*- 
     1# -*- coding: iso-8859-1 -*- 
    22""" 
    33This macro shows a quick and dirty way to make a table-of-contents for a set 
Note: See TracChangeset for help on using the changeset viewer.