All pastes #42061 Raw Edit

matt

public text v1 · immutable
#42061 ·published 2006-02-18 16:48 UTC
rendered paste body
=== trac/db/sqlite_backend.py==================================================================--- trac/db/sqlite_backend.py	(revision 8584)+++ trac/db/sqlite_backend.py	(local)@@ -21,6 +21,10 @@ from trac.db.api import IDatabaseConnector from trac.db.util import ConnectionWrapper +def escape_percent(sql):+    import re+    return re.sub("'((?:[^']|(?:''))*)'", lambda m: m.group(0).replace('%', '%%'), sql)+ try:     import pysqlite2.dbapi2 as sqlite     have_pysqlite = 2@@ -34,12 +38,12 @@                 raise         def execute(self, sql, args=None):             if args:-                sql = sql % (('?',) * len(args))+                sql = escape_percent(sql) % (('?',) * len(args))             return self._rollback_on_error(sqlite.Cursor.execute, sql,                                            args or [])         def executemany(self, sql, args=None):             if args:-                sql = sql % (('?',) * len(args[0]))+                sql = escape_percent(sql) % (('?',) * len(args[0]))             return self._rollback_on_error(sqlite.Cursor.executemany, sql,                                            args or [])         def _convert_row(self, row):@@ -61,6 +65,20 @@     try:         import sqlite         have_pysqlite = 1++        class EscapeCursor(sqlite.Cursor):++            def execute(self, sql, args=None):+                # use [] instead of calling "execute" without args to make sure+                # the '%%' escapes are converted back to a single '%'+                return sqlite.Cursor.execute(self, escape_percent(sql),+                                             args or [])++            def executemany(self, sql, args=None):+                # see note regarding args for "execute"+                return sqlite.Cursor.executemany(self, escape_percent(sql),+                                                 args or [])+     except ImportError:         have_pysqlite = 0 === trac/ticket/report.py==================================================================--- trac/ticket/report.py	(revision 8584)+++ trac/ticket/report.py	(local)@@ -448,18 +448,29 @@      def sql_sub_vars(self, req, sql, args):         values = []-        def repl(match):-            aname = match.group(1)+        def add_value(aname):             try:                 arg = args[aname]             except KeyError:                 raise util.TracError("Dynamic variable '$%s' not defined." % aname)             req.hdf['report.var.' + aname] = arg             values.append(arg)++        def repl(match):+            add_value(match.group(1))             return '%s' -        return re.sub("'?\$([A-Z]+)'?", repl, sql), values+        def repl_literal(match):+            add_value(match.group(1))+            return "' || %s || '" # break literal string & concatenate with arg +        var_re = re.compile("[$]([A-Z]+)")+        sql = [var_re.sub(s.startswith("'") and repl_literal or repl, s)+               for s in re.split("('(?:[^']|(?:''))*')", sql)]+        sql = ''.join(sql)+        self.log.debug(sql)+        return sql, values+     def _render_csv(self, req, cols, rows, sep=','):         req.send_response(200)         req.send_header('Content-Type', 'text/plain;charset=utf-8')