Re: Bug in Dbd-Pg?

Andrew Dunstan <[email protected]>
Newsgroups gmane.comp.db.postgresql.dbdpg
Message-ID <[email protected]>
PF wrote:
> Hi!
>
> I don't know if this is the right place to send a bug report, but here
> goes.
>
> I've got Fedora Core 5 and the following rpms:
> perl-5.8.8-5.i386.rpm
> perl-DBD-Pg-1.49-1.FC5.i386.rpm
> perl-DBI-1.52-1.fc5.i386.rpm
> postgresql-8.1.4-1.FC5.1.i386.rpm
>
> The following program makes perl segfault:
> ----
> #!/usr/bin/perl -wT
> use strict;
> use DBI;
> use DBD::Pg qw(:pg_types);
>
> my $dbh = DBI->connect("dbi:Pg:dbname=protein", "username","password",{ShowErrorStatement => 1,PrintError => 1});
> if (!defined $dbh) {die($DBI::errstr);}
>
> # Cut and pasted from http://search.cpan.org/~dbdpg/DBD-Pg-1.49/Pg.pm#COPY_support
> $dbh->do("COPY study TO STDOUT");
> my @data;
> my $x=0;
> 1 while($dbh->pg_getline($data[$x++], 100));
> pop @data; ## Remove final "\\.\n" line
> ----
> Use of uninitialized value in subroutine entry at dumpstudy line 12.
> *** glibc detected *** /usr/bin/perl: munmap_chunk(): invalid pointer:
> 0x08fff338 ***
> ======= Backtrace: =========
> /lib/libc.so.6(__libc_free+0x179)[0x48d84070]
> /usr/lib/libpq.so.4(PQfreemem+0x1d)[0x4dfd867d]
> /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/auto/DBD/Pg/Pg.so(pg_db_getline+0x13d)[0x803acd]
> /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/auto/DBD/Pg/Pg.so(XS_DBD__Pg__db_pg_getline+0x278)[0x7f7c48]
> /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/auto/DBI/DBI.so(XS_DBI_dispatch+0x22c8)[0xde6128]
> /usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libperl.so(Perl_pp_entersub+0x40d)[0x4994601d]
> /usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libperl.so(Perl_runops_standard+0x1f)[0x4993f48f]
> /usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libperl.so(perl_run
> +0x2ee)[0x498e4dde]
> /usr/bin/perl(main+0x13e)[0x804934e]
> /lib/libc.so.6(__libc_start_main+0xdc)[0x48d324e4]
> /usr/bin/perl[0x8049181]
> ...
> ----
> The statement "Copy study to stdout;" works fine with psql, the
> command-line client.  The table has only three records, but the records
> are longer than 100 characters, which was the buffer size in the
> pg_getline statement.  When the 100 is changed to a 500, the problem
> goes away.
>
> This is going to be a problem with another table I have, which has
> 'text' fields of unknown size, if I have to know the size before I use
> 'copy'.
>
>
>   

Looking at the code I see this in dbdimp.c:

            strncpy(buffer, tempbuf, strlen(tempbuf)+1);
            buffer[strlen(tempbuf)] = '\0';
          

However, there is no check that buffer has enough space - the code just 
seems to assume it, which seems like a bug - that code is probably 
clobbering something important. I don't quite understand why we don't 
simply make an SV straight from tmpbuf, rather than copying to a fixed 
buffer anyway. PQgetCopyData() doesn't require a length param (unlike 
the now deprecated PQgetline()), and it seems very un-perlish for us to 
require it of the user at all.

cheers

andrew
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.