Subject: | incorrect memory allocation related to quote() makes cygwin perl segfault, patch attached |
Problem appears in both 1.31 and 1.32_1, patch applies to both.
Basically, quote() uses free when it should use Safefree(), and quote_bytea() uses safefree() when it should use PQfreemem(). Also, the return type of quote() is void and writes the return value to ST(0), cygwin Perl doesn't like that very much, using areturn type of SV* and RETVAL works much better.
Original bug report:
http://www.cygwin.com/ml/cygwin/2004-02/msg00742.html
uname -a output:
CYGWIN_NT-5.1 ISIS 1.5.8(0.110/4/2) 2004-02-14 19:04 i686 unknown unknown Cygwin
perl -V output:
Summary of my perl5 (revision 5.0 version 8 subversion 2) configuration:
Platform:
osname=cygwin, osvers=1.5.5(0.9432), archname=cygwin-thread-multi-64int
uname='cygwin_nt-5.0 troubardix 1.5.5(0.9432) 2003-09-20 16:31 i686 unknown unknown cygwin '
config_args='-de -Dmksymlinks -Duse64bitint -Dusethreads -Doptimize=-O2 -Dman3ext=3pm'
hint=recommended, useposix=true, d_sigaction=define
usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=define use64bitall=undef uselongdouble=undef
usemymalloc=y, bincompat5005=undef
Compiler:
cc='gcc', ccflags ='-DPERL_USE_SAFE_PUTENV -fno-strict-aliasing',
optimize='-O2',
cppflags='-DPERL_USE_SAFE_PUTENV -fno-strict-aliasing'
ccversion='', gccversion='3.3.1 (cygming special)', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='ld2', ldflags =' -s -L/usr/local/lib'
libpth=/usr/local/lib /usr/lib /lib
libs=-lgdbm -ldb -lcrypt -lgdbm_compat
perllibs=-lcrypt -lgdbm_compat
libc=/usr/lib/libc.a, so=dll, useshrplib=true, libperl=libperl.a
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' -s'
cccdlflags=' ', lddlflags=' -s -L/usr/local/lib'
Characteristics of this binary (from libperl):
Compile-time options: MULTIPLICITY USE_ITHREADS USE_64_BIT_INT USE_LARGE_FILES PERL_IMPLICIT_CONTEXT
Built under cygwin
Compiled at Nov 7 2003 12:06:28
%ENV:
PERLDOC_PAGER="less -isrRqX"
CYGWIN="tty export glob ntsec winsymlinks check_case:strict server"
@INC:
/usr/lib/perl5/5.8.2/cygwin-thread-multi-64int
/usr/lib/perl5/5.8.2
/usr/lib/perl5/site_perl/5.8.2/cygwin-thread-multi-64int
/usr/lib/perl5/site_perl/5.8.2
/usr/lib/perl5/site_perl
.
diff -ruN DBD-Pg-1.31.orig/Pg.xs DBD-Pg-1.31/Pg.xs
--- DBD-Pg-1.31.orig/Pg.xs 2003-10-29 13:13:32.000000000 -0800
+++ DBD-Pg-1.31/Pg.xs 2004-02-17 01:55:03.000000000 -0800
@@ -70,7 +70,7 @@
#TODO: make quote(foo, {type=>SQL_INTEGER}) work #rl
#TODO: make quote(foo, {pg_type=>DBD::Pg::PG_INTEGER}) work #rl
-void
+SV*
quote(dbh, to_quote_sv, type_sv=Nullsv)
SV* dbh
SV* to_quote_sv
@@ -104,17 +104,19 @@
if (!SvOK(to_quote_sv)) {
quoted = "NULL";
len = 4;
- ST(0) = sv_2mortal(newSVpv(quoted,len));
+ RETVAL = newSVpvn(quoted,len);
} else {
if (SvMAGICAL(to_quote_sv))
mg_get(to_quote_sv);
to_quote = SvPV(to_quote_sv, len);
quoted = type_info->quote(to_quote, len, &retlen);
- ST(0) = sv_2mortal(newSVpv(quoted, retlen));
- free (quoted);
+ RETVAL = newSVpvn(quoted, retlen);
+ Safefree (quoted);
}
}
+ OUTPUT:
+ RETVAL
diff -ruN DBD-Pg-1.31.orig/quote.c DBD-Pg-1.31/quote.c
--- DBD-Pg-1.31.orig/quote.c 2003-10-29 13:13:32.000000000 -0800
+++ DBD-Pg-1.31/quote.c 2004-02-17 02:26:23.000000000 -0800
@@ -373,7 +373,7 @@
strcpy(dest,intermead);
strcat(dest,"\'");
- safefree(intermead);
+ PQfreemem(intermead);
*retlen=strlen(result);
assert(*retlen+1 <= resultant_len+2);