-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello,

I believe I have found a bug in the DB-API 2 interface provided by
PyGreSQL 4.0. If you try to do something like:

some_curs.execute("""INSERT INTO bin_table
                                 (bin_column)
                          VALUES (%(bin_data)s)""",
                  {'data': pgdb.Binary('\xff\x52\xb2')})

You'll get an error like:
ERROR:  invalid byte sequence for encoding "UTF8": 0xff
HINT:  This error can also happen if the byte sequence does not match
the encoding expected by the server, which is controlled by
"client_encoding".
' in 'INSERT INTO binary_escaping_bug (bin_data) VALUES ('<Removed as
not to mess with peoples mail clients>')


I have attached a python script which demonstrates this bug, and a patch
that fixes this. I am happy to rework the patch if I'm not doing things
the right way.

Thanks,
Dan McDonald
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkrgfZQACgkQOZjwGnHLcvi5BQCfdq0WIk5AQ+fNEmp2xeGyNApd
nDUAoLV+JTGW77aNiVUClD7sX3OVPBAI
=kUTW
-----END PGP SIGNATURE-----

Attachment: pgdb_binary_escaping_bug.py
Description: application/python

--- /usr/lib64/python2.6/site-packages/pgdb.py  2009-01-01 06:05:02.000000000 
-0700
+++ /usr/lib64/python2.6/site-packages/pgdb_fixed.py    2009-10-22 
09:30:29.000000000 -0600
@@ -191,7 +191,9 @@
             val = str(val)
         elif isinstance(val, unicode):
             val = val.encode( 'utf8' )
-        if isinstance(val, str):
+        if isinstance(val, Binary):
+            val = val.quoted()
+        elif isinstance(val, str):
             val = "'%s'" % self._cnx.escape_string(val)
         elif isinstance(val, (int, long, float)):
             pass
@@ -568,9 +570,13 @@
     """construct an object holding a time stamp from the given ticks value."""
     return Timestamp(*time.localtime(ticks)[:6])
 
-def Binary(value):
-    """construct an object capable of holding a binary (long) string value."""
-    return value
+class Binary(object):
+    def __init__(self, value):
+        """construct an object capable of holding a binary (long) string 
value."""
+        self.value = value
+    
+    def quoted(self):
+        return "E'%s'" % escape_bytea(self.value)
 
 
 # If run as script, print some information:

Attachment: pgdb_binary_escaping_bug.py.sig
Description: Binary data

Attachment: pgdb_binary_escape_fix.patch.sig
Description: Binary data

_______________________________________________
PyGreSQL mailing list
[email protected]
http://mailman.vex.net/mailman/listinfo/pygresql

Reply via email to