Skip Menu |

This queue is for tickets about the DBD-Pg CPAN distribution.

Report information
The Basics
Id: 33737
Status: resolved
Priority: 0/
Queue: DBD-Pg

People
Owner: Nobody in particular
Requestors: ATOURBIN [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 2.0.0
Fixed in: 2.2.1



Subject: dbdimp.c: fixed 'str[strlen(str)]' code
Hello, This code: Show quoted text
> /* Strip final newline so line number appears for warn/die */ > if (err[strlen(err)] == 10) > err[strlen(err)] = '\0';
is simply wrong. Note that, whenever the "err" string is null-terminated, err[strlen(err)] is always '\0' (e.g. if strlen(err) == 3, then the three characters are indexed by 0, 1, and 2; and err[3] is final '\0'). The attached patch fixes this case by using sv_setpvn instead; and also another case, by using snprintf(3). -- Alexey Tourbin ALT Linux Team
Subject: DBD-Pg-2.2.0-strlen.patch
commit 226e320e687c488a3d8c80e597490e82f8450866 Author: Alexey Tourbin <at@altlinux.ru> Date: Sun Mar 2 03:14:09 2008 +0300 dbdimp.c (dbd_st_FETCH_attrib): fixed 'statement[strlen(statement)]' thinko diff --git a/dbdimp.c b/dbdimp.c index 6d559c1..ac9e860 100644 --- a/dbdimp.c +++ b/dbdimp.c @@ -1054,13 +1054,10 @@ SV * dbd_st_FETCH_attrib (SV * sth, imp_sth_t * imp_sth, SV * keysv) PGresult *result; int status = -1; D_imp_dbh_from_sth; - char *statement; int nullable; /* 0 = not nullable, 1 = nullable 2 = unknown */ int y; retsv = newRV(sv_2mortal((SV*)av)); - New(0, statement, 100, char); /* freed below */ - statement[0] = '\0'; while(--fields >= 0) { nullable=2; TRACE_PQFTABLE; @@ -1068,9 +1065,10 @@ SV * dbd_st_FETCH_attrib (SV * sth, imp_sth_t * imp_sth, SV * keysv) TRACE_PQFTABLECOL; y = PQftablecol(imp_sth->result, fields); if (InvalidOid != x && y > 0) { /* We know what table and column this came from */ - sprintf(statement, + char statement[128]; + + snprintf(statement, sizeof(statement), "SELECT attnotnull FROM pg_catalog.pg_attribute WHERE attrelid=%d AND attnum=%d", x, y); - statement[strlen(statement)]='\0'; TRACE_PQEXEC; result = PQexec(imp_dbh->conn, statement); TRACE_PQRESULTSTATUS; @@ -1095,7 +1093,6 @@ SV * dbd_st_FETCH_attrib (SV * sth, imp_sth_t * imp_sth, SV * keysv) } (void)av_store(av, fields, newSViv(nullable)); } - Safefree(statement); } break; commit da86ebbed3e67a954414e30aca5316e593c240ce Author: Alexey Tourbin <at@altlinux.ru> Date: Sun Mar 2 03:05:39 2008 +0300 dbdimp.c (pg_error): fixed 'err[strlen(err)]' code Note that 'err[strlen(err)]' is always '\0'. diff --git a/dbdimp.c b/dbdimp.c index bdf890b..6d559c1 100644 --- a/dbdimp.c +++ b/dbdimp.c @@ -271,23 +271,21 @@ int dbd_db_login (SV * dbh, imp_dbh_t * imp_dbh, char * dbname, char * uid, char static void pg_error (pTHX_ SV * h, ExecStatusType error_num, const char * error_msg) { D_imp_xxh(h); - char * err; + size_t error_len; imp_dbh_t * imp_dbh = (imp_dbh_t *)(DBIc_TYPE(imp_xxh) == DBIt_ST ? DBIc_PARENT_COM(imp_xxh) : imp_xxh); if (TSTART) TRC(DBILOGFP, "%sBegin pg_error (message: %s number: %d)\n", THEADER, error_msg, error_num); - New(0, err, strlen(error_msg)+1, char); /* freed below */ - strcpy(err, error_msg); + error_len = strlen(error_msg); /* Strip final newline so line number appears for warn/die */ - if (err[strlen(err)] == 10) - err[strlen(err)] = '\0'; + if (error_len > 0 && error_msg[error_len-1] == 10) + error_len--; sv_setiv(DBIc_ERR(imp_xxh), (IV)error_num); - sv_setpv(DBIc_ERRSTR(imp_xxh), (char*)err); + sv_setpvn(DBIc_ERRSTR(imp_xxh), (char*)error_msg, error_len); sv_setpv(DBIc_STATE(imp_xxh), (char*)imp_dbh->sqlstate); - Safefree(err); if (TEND) TRC(DBILOGFP, "%sEnd pg_error\n", THEADER);
Thank you very much: your changes were applied in r10858 and will be a part of the next version, 2.2.1.