ecpg: numeric_div error handling - Mailing list pgsql-patches
From | Neil Conway |
---|---|
Subject | ecpg: numeric_div error handling |
Date | |
Msg-id | 42C4A421.5060802@samurai.com Whole thread Raw |
Responses |
Re: ecpg: numeric_div error handling
|
List | pgsql-patches |
This patch adds some missing error handling to PGTYPESnumeric_div() in ecpg's pgtypeslib: (1) we need to check the return value of sub_abs() (2) we need to check the return value of 4 calls to digitbuf_alloc(). Per Coverity static analysis by EDB. Barring any objections I'll apply this to CVS later today. -Neil Index: src/interfaces/ecpg/pgtypeslib/numeric.c =================================================================== RCS file: /var/lib/cvs/pgsql/src/interfaces/ecpg/pgtypeslib/numeric.c,v retrieving revision 1.21 diff -c -r1.21 numeric.c *** src/interfaces/ecpg/pgtypeslib/numeric.c 24 May 2005 02:09:45 -0000 1.21 --- src/interfaces/ecpg/pgtypeslib/numeric.c 1 Jul 2005 01:47:51 -0000 *************** *** 1096,1101 **** --- 1096,1103 ---- int stat = 0; int rscale; int res_dscale = select_div_scale(var1, var2, &rscale); + int err = -1; + NumericDigit *tmp_buf; /* * First of all division by zero check *************** *** 1143,1148 **** --- 1145,1152 ---- divisor[1].rscale = var2->ndigits; divisor[1].sign = NUMERIC_POS; divisor[1].buf = digitbuf_alloc(ndigits_tmp); + if (divisor[1].buf == NULL) + goto done; divisor[1].digits = divisor[1].buf; divisor[1].digits[0] = 0; memcpy(&(divisor[1].digits[1]), var2->digits, ndigits_tmp - 1); *************** *** 1155,1168 **** dividend.rscale = var1->ndigits; dividend.sign = NUMERIC_POS; dividend.buf = digitbuf_alloc(var1->ndigits); dividend.digits = dividend.buf; memcpy(dividend.digits, var1->digits, var1->ndigits); /* ! * Setup the result */ digitbuf_free(result->buf); ! result->buf = digitbuf_alloc(res_ndigits + 2); res_digits = result->buf; result->digits = res_digits; result->ndigits = res_ndigits; --- 1159,1179 ---- dividend.rscale = var1->ndigits; dividend.sign = NUMERIC_POS; dividend.buf = digitbuf_alloc(var1->ndigits); + if (dividend.buf == NULL) + goto done; dividend.digits = dividend.buf; memcpy(dividend.digits, var1->digits, var1->ndigits); /* ! * Setup the result. Do the allocation in a temporary buffer ! * first, so we don't free result->buf unless we have successfully ! * allocated a buffer to replace it with. */ + tmp_buf = digitbuf_alloc(res_ndigits + 2); + if (tmp_buf == NULL) + goto done; digitbuf_free(result->buf); ! result->buf = tmp_buf; res_digits = result->buf; result->digits = res_digits; result->ndigits = res_ndigits; *************** *** 1201,1206 **** --- 1212,1219 ---- memcpy(&divisor[guess], &divisor[1], sizeof(numeric)); divisor[guess].buf = digitbuf_alloc(divisor[guess].ndigits); + if (divisor[guess].buf == NULL) + goto done; divisor[guess].digits = divisor[guess].buf; for (i = divisor[1].ndigits - 1; i >= 0; i--) { *************** *** 1233,1239 **** if (guess == 0) continue; ! sub_abs(÷nd, &divisor[guess], ÷nd); first_nextdigit = dividend.weight - weight_tmp; first_have = 0; --- 1246,1253 ---- if (guess == 0) continue; ! if (sub_abs(÷nd, &divisor[guess], ÷nd) != 0) ! goto done; first_nextdigit = dividend.weight - weight_tmp; first_have = 0; *************** *** 1269,1283 **** if (result->ndigits == 0) result->sign = NUMERIC_POS; /* * Tidy up */ ! digitbuf_free(dividend.buf); for (i = 1; i < 10; i++) ! digitbuf_free(divisor[i].buf); ! result->dscale = res_dscale; ! return 0; } --- 1283,1305 ---- if (result->ndigits == 0) result->sign = NUMERIC_POS; + result->dscale = res_dscale; + err = 0; /* if we've made it this far, return success */ + + done: /* * Tidy up */ ! if (dividend.buf != NULL) ! digitbuf_free(dividend.buf); ! for (i = 1; i < 10; i++) ! { ! if (divisor[i].buf != NULL) ! digitbuf_free(divisor[i].buf); ! } ! return err; }
pgsql-patches by date: