segfault with pg_getcopydata in DBD::Pg 2.6.1

David Harris <[email protected]>
Newsgroups gmane.comp.db.postgresql.dbdpg
Message-ID <[email protected]>
Hi,

I've tracked down a segfault in DBD::Pg 2.6.1, and I've got a patch.

Version: DBD-Pg-2.6.1 (also had problem with DBD-Pg-2.1.3)
Other versions: Perl-5.8.8, DBI-1.602
System: CentOS release 5 (Final), Linux centos5.drh.net 2.6.18-8.el5

With this perl code:

 >>>
         $dbh->do(q[ COPY ( SELECT * FROM table_with_no_rows ) TO  
STDOUT WITH DELIMITER ',' ]);
         my $data;
         my $last = 0;
         while ( ! $last )
         {
             $last = $dbh->pg_getcopydata($data) == -1;

             # do stuff.
         }
<<<

I got a segfault from pg_getcopydata when the query returned no rows.  
It worked fine when the query did return rows.

Here's the info from gdb on the segfault:

 >>>
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1208076608 (LWP 24340)]
0x00f8bb56 in pg_db_getcopydata (dbh=0x8ca9534, dataline=0x8de7320,  
async=0) at dbdimp.c:3672
3672                    SvCUR_set(dataline, 0);
(gdb) p dataline
$1 = (SV *) 0x8de7320
(gdb) p *dataline
$2 = {sv_any = 0x0, sv_refcnt = 1, sv_flags = 1280}
<<<

Here's the patch:

 >>>
--- DBD-Pg-2.6.1.orig/dbdimp.c  2008-04-22 12:56:32.000000000 -0500
+++ DBD-Pg-2.6.1/dbdimp.c       2008-04-30 05:03:22.000000000 -0500
@@ -3664,7 +3664,7 @@
         else if (-1 == copystatus) {
                 PGresult * result;
                 ExecStatusType status;
-               SvCUR_set(dataline, 0);
+               sv_setpv(dataline, "");
                 imp_dbh->copystate=0;
                 TRACE_PQGETRESULT;
                 result = PQgetResult(imp_dbh->conn);
<<<

If pg_getcopydata is called and the buffer variable is a freshly  
defined variable and copystatus == -1, then the SvCUR_set call  
segfaults because there is no string component allocated for this SV,  
so the length of the string component can't be set to zero. I changed  
to using the sv_setpv() call to just set it to a zero length string.  
This fixes the segfault in my case.

I'm not a perl internals expert, so you might want to double check this.

Thanks!

David
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.