Committed by Greg Sabino Mullane <[email protected]>

Add a call to $dbh->{pg_placeholder_escapes} = 0 as an
emergency measure in case the new backslash escape system breaks something.
It is very unlikely to do so - and this will probably be removed entirely
after a few versions.

---
 Pg.pm              |  1 +
 dbdimp.c           | 21 +++++++++++++++++----
 dbdimp.h           |  1 +
 t/12placeholders.t | 14 ++++++++++++--
 4 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/Pg.pm b/Pg.pm
index 703f882..948db96 100644
--- a/Pg.pm
+++ b/Pg.pm
@@ -1584,6 +1584,7 @@ use 5.008001;
                 pg_pid                         => undef,
                 pg_placeholder_dollaronly      => undef,
                 pg_placeholder_nocolons        => undef,
+                pg_placeholder_escapes         => undef,
                 pg_port                        => undef,
                 pg_prepare_now                 => undef,
                 pg_protocol                    => undef,
diff --git a/dbdimp.c b/dbdimp.c
index c90d561..543b7c5 100644
--- a/dbdimp.c
+++ b/dbdimp.c
@@ -237,6 +237,7 @@ int dbd_db_login6 (SV * dbh, imp_dbh_t * imp_dbh, char * 
dbname, char * uid, cha
        imp_dbh->done_begin        = DBDPG_FALSE;
        imp_dbh->dollaronly        = DBDPG_FALSE;
        imp_dbh->nocolons          = DBDPG_FALSE;
+       imp_dbh->ph_escaped        = DBDPG_TRUE;
        imp_dbh->expand_array      = DBDPG_TRUE;
        imp_dbh->txn_read_only     = DBDPG_FALSE;
        imp_dbh->pid_number        = getpid();
@@ -970,6 +971,14 @@ int dbd_db_STORE_attrib (SV * dbh, imp_dbh_t * imp_dbh, SV 
* keysv, SV * valuesv
                }
                break;
 
+       case 22: /* pg_placeholder_escaped */
+
+               if (strEQ("pg_placeholder_escaped", key)) {
+                       imp_dbh->ph_escaped = newval ? DBDPG_TRUE : DBDPG_FALSE;
+                       retval = 1;
+               }
+               break;
+
        case 23: /* pg_placeholder_nocolons */
 
                if (strEQ("pg_placeholder_nocolons", key)) {
@@ -1979,15 +1988,19 @@ static void pg_st_split_statement (pTHX_ imp_sth_t * 
imp_sth, int version, char
                        continue;
                }
 
-               /* If this placeholder is escaped, we rewrite the string to 
remove the
-                  backslash, and move on as if there is no placeholder */
-               if ('\\' == oldch) {
+               /*
+                 If this placeholder is escaped, we rewrite the string to 
remove the
+                 backslash, and move on as if there is no placeholder.
+                 The use of $dbh->{pg_placeholder_escaped} = 0 is left as an 
emergency measure.
+                 It will probably be removed at some point.
+               */
+               if ('\\' == oldch && imp_dbh->ph_escaped) {
                        /* copy the placeholder-like character but ignore the 
backslash */
                        unsigned char *p = statement-2;
                        while(*p++) {
                                *(p-1) = *p;
                        }
-                       /* We need to adjust these items because we just 
rewrote statement! */
+                       /* We need to adjust these items because we just 
rewrote 'statement'! */
                        statement--;
                        currpos--;
                        ch = *statement;
diff --git a/dbdimp.h b/dbdimp.h
index 5bddc3a..06af917 100644
--- a/dbdimp.h
+++ b/dbdimp.h
@@ -37,6 +37,7 @@ struct imp_dbh_st {
        bool    done_begin;        /* have we done a begin? (e.g. are we in a 
transaction?) */
        bool    dollaronly;        /* only consider $1, $2 ... as valid 
placeholders */
        bool    nocolons;          /* do not consider :1, :2 ... as valid 
placeholders */
+       bool    ph_escaped;        /* allow backslash to escape placeholders */
        bool    expand_array;      /* transform arrays from the db into Perl 
arrays? Default is 1 */
        bool    txn_read_only;     /* are we in read-only mode? Set with 
$dbh->{ReadOnly} */
 
diff --git a/t/12placeholders.t b/t/12placeholders.t
index cfd7164..254903d 100644
--- a/t/12placeholders.t
+++ b/t/12placeholders.t
@@ -17,7 +17,7 @@ my $dbh = connect_database();
 if (! $dbh) {
        plan skip_all => 'Connection to database failed, cannot continue 
testing';
 }
-plan tests => 253;
+plan tests => 254;
 
 my $t='Connect to database for placeholder testing';
 isnt ($dbh, undef, $t);
@@ -867,7 +867,17 @@ eval {
 is($@, '', $t);
 $sth->finish();
 
-## pg_placeholder_escaping = 1;
+## This is an emergency hatch only. Hopefully will never be used in the wild!
+$dbh->{pg_placeholder_escaped} = 0;
+$t = q{Basic placeholder escaping fails when pg_placeholder_escaped is set to 
false};
+$SQL = qq{SELECT count(*) FROM dbd_pg_test WHERE pname \\?\\? ?};
+$sth = $dbh->prepare($SQL);
+eval {
+       $count = $sth->execute('foobar');
+};
+like($@, qr{execute}, $t);
+$sth->finish();
+
 
 ## Begin custom type testing
 
-- 
1.8.4

Reply via email to