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