# HG changeset patch # User Vadim Gelfer # Date 1141061743 28800 # Node ID c64bef3d70432f618728c58bbe04e564ac5c9230 # Parent f2815605186e33e2bc14a1a74361618452a98be2 use safer string parser for template engine. diff -r f2815605186e -r c64bef3d7043 mercurial/templater.py --- a/mercurial/templater.py Mon Feb 27 09:15:59 2006 -0800 +++ b/mercurial/templater.py Mon Feb 27 09:35:43 2006 -0800 @@ -1,6 +1,32 @@ import re from demandload import demandload -demandload(globals(), "cgi os time urllib util") +from i18n import gettext as _ +demandload(globals(), "cStringIO cgi os time urllib util") + +esctable = { + '\\': '\\', + 'r': '\r', + 't': '\t', + 'n': '\n', + 'v': '\v', + } + +def parsestring(s): + fp = cStringIO.StringIO() + escape = False + first = s[0] + if len(s) < 2: raise SyntaxError(_('string too short')) + if first not in "'\"": raise SyntaxError(_('invalid quote')) + if s[-1] != first: raise SyntaxError(_('unmatched quotes')) + for c in s[1:-1]: + if escape: + fp.write(esctable.get(c, c)) + escape = False + elif c == '\\': escape = True + elif c == first: raise SyntaxError(_('string ends early')) + else: fp.write(c) + if escape: raise SyntaxError(_('unterminated escape')) + return fp.getvalue() class templater(object): def __init__(self, mapfile, filters={}, defaults={}): @@ -10,10 +36,16 @@ self.filters = filters self.defaults = defaults + i = 0 for l in file(mapfile): - m = re.match(r'(\S+)\s*=\s*(".*"|\'.*\')$', l) + i += 1 + m = re.match(r'(\S+)\s*=\s*(["\'].*["\'])$', l) if m: - self.cache[m.group(1)] = eval(m.group(2)) + try: + s = m.group(2) + self.cache[m.group(1)] = parsestring(s) + except SyntaxError, inst: + raise SyntaxError('%s:%s: %s' % (mapfile, i, inst.args[0])) else: m = re.match(r'(\S+)\s*=\s*(\S+)', l) if m: diff -r f2815605186e -r c64bef3d7043 templates/map --- a/templates/map Mon Feb 27 09:15:59 2006 -0800 +++ b/templates/map Mon Feb 27 09:35:43 2006 -0800 @@ -1,50 +1,50 @@ -default = "changelog" +default = 'changelog' header = header.tmpl footer = footer.tmpl search = search.tmpl changelog = changelog.tmpl -naventry = "#label|escape# " -filedifflink = "#file|escape# " -filenodelink = "#file|escape# " -fileellipses = "..." +naventry = '#label|escape# ' +filedifflink = '#file|escape# ' +filenodelink = '#file|escape# ' +fileellipses = '...' changelogentry = changelogentry.tmpl searchentry = changelogentry.tmpl changeset = changeset.tmpl manifest = manifest.tmpl -manifestdirentry = "drwxr-xr-x #basename|escape#/" -manifestfileentry = "#permissions|permissions# #basename|escape#" +manifestdirentry = 'drwxr-xr-x #basename|escape#/' +manifestfileentry = '#permissions|permissions# #basename|escape#' filerevision = filerevision.tmpl fileannotate = fileannotate.tmpl filediff = filediff.tmpl filelog = filelog.tmpl -fileline = "
#linenumber##line|escape#
" +fileline = '
#linenumber##line|escape#
' filelogentry = filelogentry.tmpl -annotateline = "#author|obfuscate#@#rev#
#line|escape#
" -difflineplus = "#line|escape#" -difflineminus = "#line|escape#" -difflineat = "#line|escape#" -diffline = "#line|escape#" -changelogparent = "parent #rev#:#node|short#" -changesetparent = "parent #rev#:#node|short#" -filerevparent = "parent:#node|short#" -filerename = "parent:#file|escape#@#node|short#" -filelogrename = "base: #file|escape#@#node|short#" -fileannotateparent = "parent:#node|short#" -changesetchild = "child #rev#:#node|short#" -changelogchild = "child #rev#:#node|short#" -filerevchild = "child:#node|short#" -fileannotatechild = "child:#node|short#" +annotateline = '#author|obfuscate#@#rev#
#line|escape#
' +difflineplus = '#line|escape#' +difflineminus = '#line|escape#' +difflineat = '#line|escape#' +diffline = '#line|escape#' +changelogparent = 'parent #rev#:#node|short#' +changesetparent = 'parent #rev#:#node|short#' +filerevparent = 'parent:#node|short#' +filerename = 'parent:#file|escape#@#node|short#' +filelogrename = 'base: #file|escape#@#node|short#' +fileannotateparent = 'parent:#node|short#' +changesetchild = 'child #rev#:#node|short#' +changelogchild = 'child #rev#:#node|short#' +filerevchild = 'child:#node|short#' +fileannotatechild = 'child:#node|short#' tags = tags.tmpl -tagentry = "
  • #node# #tag|escape#
  • " -diffblock = "
    #lines#
    " -changelogtag = "tag:#tag|escape#" -changesettag = "tag:#tag|escape#" -filediffparent = "parent #rev#:#node|short#" -filelogparent = "parent #rev#: #node|short#" -filediffchild = "child #rev#:#node|short#" -filelogchild = "child #rev#: #node|short#" -indexentry = "#name|escape##shortdesc##contact|obfuscate##lastupdate|age# agoRSS" +tagentry = '
  • #node# #tag|escape#
  • ' +diffblock = '
    #lines#
    ' +changelogtag = 'tag:#tag|escape#' +changesettag = 'tag:#tag|escape#' +filediffparent = 'parent #rev#:#node|short#' +filelogparent = 'parent #rev#: #node|short#' +filediffchild = 'child #rev#:#node|short#' +filelogchild = 'child #rev#: #node|short#' +indexentry = '#name|escape##shortdesc##contact|obfuscate##lastupdate|age# agoRSS' index = index.tmpl -archiveentry = "#type|escape# " +archiveentry = '#type|escape# ' notfound = notfound.tmpl error = error.tmpl diff -r f2815605186e -r c64bef3d7043 templates/map-gitweb --- a/templates/map-gitweb Mon Feb 27 09:15:59 2006 -0800 +++ b/templates/map-gitweb Mon Feb 27 09:35:43 2006 -0800 @@ -1,50 +1,50 @@ -default = "summary" +default = 'summary' header = header-gitweb.tmpl footer = footer-gitweb.tmpl search = search-gitweb.tmpl changelog = changelog-gitweb.tmpl summary = summary-gitweb.tmpl error = error-gitweb.tmpl -naventry = "#label|escape# " -navshortentry = "#label|escape# " -filedifflink = "#file|escape# " -filenodelink = "#file|escape#file | revisions" -fileellipses = "..." +naventry = '#label|escape# ' +navshortentry = '#label|escape# ' +filedifflink = '#file|escape# ' +filenodelink = '#file|escape#file | revisions' +fileellipses = '...' changelogentry = changelogentry-gitweb.tmpl searchentry = changelogentry-gitweb.tmpl changeset = changeset-gitweb.tmpl manifest = manifest-gitweb.tmpl -manifestdirentry = "drwxr-xr-x#basename|escape#/manifest" -manifestfileentry = "#permissions|permissions##basename|escape#file | revisions | annotate" +manifestdirentry = 'drwxr-xr-x#basename|escape#/manifest' +manifestfileentry = '#permissions|permissions##basename|escape#file | revisions | annotate' filerevision = filerevision-gitweb.tmpl fileannotate = fileannotate-gitweb.tmpl filelog = filelog-gitweb.tmpl -fileline = "
    #linenumber# #line|escape#
    " -annotateline = "#author|obfuscate#@#rev##line|escape#" -difflineplus = "
    #line|escape#
    " -difflineminus = "
    #line|escape#
    " -difflineat = "
    #line|escape#
    " -diffline = "
    #line|escape#
    " -changelogparent = "parent #rev#:#node|short#" -changesetparent = "parent#node|short#" -filerevparent = "parent:#node|short#" -filerename = "parent:#file|escape#@#node|short#" -filelogrename = "| base" -fileannotateparent = "parent:#node|short#" -changelogchild = "child #rev#:#node|short#" -changesetchild = "child#node|short#" -filerevchild = "child:#node|short#" -fileannotatechild = "child:#node|short#" +fileline = '
    #linenumber# #line|escape#
    ' +annotateline = '#author|obfuscate#@#rev##line|escape#' +difflineplus = '
    #line|escape#
    ' +difflineminus = '
    #line|escape#
    ' +difflineat = '
    #line|escape#
    ' +diffline = '
    #line|escape#
    ' +changelogparent = 'parent #rev#:#node|short#' +changesetparent = 'parent#node|short#' +filerevparent = 'parent:#node|short#' +filerename = 'parent:#file|escape#@#node|short#' +filelogrename = '| base' +fileannotateparent = 'parent:#node|short#' +changelogchild = 'child #rev#:#node|short#' +changesetchild = 'child#node|short#' +filerevchild = 'child:#node|short#' +fileannotatechild = 'child:#node|short#' tags = tags-gitweb.tmpl -tagentry = "#date|age# ago#tag|escape#changeset | changelog | manifest" -diffblock = "#lines#" -changelogtag = "tag:#tag|escape#" -changesettag = "tag#tag|escape#" -filediffparent = "parent #rev#:#node|short#" -filelogparent = "parent #rev#: #node|short#" -filediffchild = "child #rev#:#node|short#" -filelogchild = "child #rev#: #node|short#" +tagentry = '#date|age# ago#tag|escape#changeset | changelog | manifest' +diffblock = '#lines#' +changelogtag = 'tag:#tag|escape#' +changesettag = 'tag#tag|escape#' +filediffparent = 'parent #rev#:#node|short#' +filelogparent = 'parent #rev#: #node|short#' +filediffchild = 'child #rev#:#node|short#' +filelogchild = 'child #rev#: #node|short#' shortlog = shortlog-gitweb.tmpl -shortlogentry = "#date|age# ago#desc|firstline|escape#changeset | manifest" -filelogentry = "#date|age# ago#desc|firstline|escape# annotate #rename%filelogrename#" -archiveentry = " | #type|escape# " +shortlogentry = '#date|age# ago#desc|firstline|escape#changeset | manifest' +filelogentry = '#date|age# ago#desc|firstline|escape# annotate #rename%filelogrename#' +archiveentry = ' | #type|escape# ' diff -r f2815605186e -r c64bef3d7043 templates/map-raw --- a/templates/map-raw Mon Feb 27 09:15:59 2006 -0800 +++ b/templates/map-raw Mon Feb 27 09:35:43 2006 -0800 @@ -1,16 +1,16 @@ header = header-raw.tmpl -footer = "" +footer = '' changeset = changeset-raw.tmpl -difflineplus = "#line#" -difflineminus = "#line#" -difflineat = "#line#" -diffline = "#line#" -changesetparent = "# parent: #node#" -changesetchild = "# child: #node#" -filenodelink = "" +difflineplus = '#line#' +difflineminus = '#line#' +difflineat = '#line#' +diffline = '#line#' +changesetparent = '# parent: #node#' +changesetchild = '# child: #node#' +filenodelink = '' filerevision = filerevision-raw.tmpl -fileline = "#line#" -diffblock = "#lines#" +fileline = '#line#' +diffblock = '#lines#' filediff = filediff-raw.tmpl fileannotate = fileannotate-raw.tmpl -annotateline = "#author#@#rev#: #line#" +annotateline = '#author#@#rev#: #line#' diff -r f2815605186e -r c64bef3d7043 templates/map-rss --- a/templates/map-rss Mon Feb 27 09:15:59 2006 -0800 +++ b/templates/map-rss Mon Feb 27 09:35:43 2006 -0800 @@ -1,4 +1,4 @@ -default = "changelog" +default = 'changelog' header = header-rss.tmpl changelog = changelog-rss.tmpl changelogentry = changelogentry-rss.tmpl