Re: Bug in Dbd-Pg?

Andrew Dunstan <[email protected]>
Newsgroups gmane.comp.db.postgresql.dbdpg
Message-ID <[email protected]>
I wrote:
> 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.
>
>


Here is an untested patch that will grow the buffer as needed, I hope. 
It doesn't make the length param go away, but it makes it mostly 
irrelevant :-)

cheers

andrew
dbd-patch (text/plain, 1.6 KB)
--- dbdimp.c.orig	2006-12-28 11:05:08.000000000 -0500
+++ dbdimp.c	2006-12-28 11:18:17.000000000 -0500
@@ -2794,14 +2794,15 @@
 
 /* ================================================================== */
 int
-pg_db_getline (dbh, buffer, length)
+pg_db_getline (dbh, svbuf, length)
 		SV * dbh;
-		char * buffer;
+		SV * svbuf;
 		int length;
 {
 		D_imp_dbh(dbh);
 		int copystatus;
 		char * tempbuf;
+		char * buffer = SvPV_nolen(svbuf);
 
 		if (dbis->debug >= 4)
 			(void)PerlIO_printf(DBILOGFP, "dbdpg: pg_db_getline\n");
@@ -2838,6 +2839,7 @@
 			pg_error(dbh, PGRES_FATAL_ERROR, PQerrorMessage(imp_dbh->conn));
 		}
 		else {
+		    buffer = SvGROW(svbuf, strlen(tempbuf)+1);
 			strncpy(buffer, tempbuf, strlen(tempbuf)+1);
 			buffer[strlen(tempbuf)] = '\0';
 			PQfreemem(tempbuf);
--- dbdimp.h.orig	2006-04-26 23:34:51.000000000 -0400
+++ dbdimp.h	2006-12-28 11:19:39.000000000 -0500
@@ -102,7 +102,7 @@
 int dbd_db_getfd (SV *dbh, imp_dbh_t *imp_dbh);
 SV * dbd_db_pg_notifies (SV *dbh, imp_dbh_t *imp_dbh);
 int pg_db_putline (SV *dbh, const char *buffer);
-int pg_db_getline (SV *dbh, char *buffer, int length);
+int pg_db_getline (SV *dbh, SV *svbuf, int length);
 int pg_db_endcopy (SV * dbh);
 void pg_db_pg_server_trace (SV *dbh, FILE *fh);
 void pg_db_pg_server_untrace (SV *dbh);
--- Pg.xs.orig	2006-12-28 11:04:55.000000000 -0500
+++ Pg.xs	2006-12-28 11:13:31.000000000 -0500
@@ -406,7 +406,7 @@
 		buf = SvGROW(bufsv, 3);
 		if (len > 3)
 			buf = SvGROW(bufsv, len);
-		ret = pg_db_getline(dbh, buf, (int)len);
+		ret = pg_db_getline(dbh, bufsv, (int)len);
 		sv_setpv((SV*)ST(1), buf);
 		SvSETMAGIC(ST(1));
 		ST(0) = (-1 != ret) ? &sv_yes : &sv_no;
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.