Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 555f513

Browse files
author
Neil Conway
committed
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 performed by EnterpriseDB.
1 parent 9fad4cb commit 555f513

File tree

1 file changed

+29
-7
lines changed

1 file changed

+29
-7
lines changed

src/interfaces/ecpg/pgtypeslib/numeric.c

+29-7
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,8 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
10961096
int stat = 0;
10971097
int rscale;
10981098
int res_dscale = select_div_scale(var1, var2, &rscale);
1099+
int err = -1;
1100+
NumericDigit *tmp_buf;
10991101

11001102
/*
11011103
* First of all division by zero check
@@ -1143,6 +1145,8 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
11431145
divisor[1].rscale = var2->ndigits;
11441146
divisor[1].sign = NUMERIC_POS;
11451147
divisor[1].buf = digitbuf_alloc(ndigits_tmp);
1148+
if (divisor[1].buf == NULL)
1149+
goto done;
11461150
divisor[1].digits = divisor[1].buf;
11471151
divisor[1].digits[0] = 0;
11481152
memcpy(&(divisor[1].digits[1]), var2->digits, ndigits_tmp - 1);
@@ -1155,14 +1159,21 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
11551159
dividend.rscale = var1->ndigits;
11561160
dividend.sign = NUMERIC_POS;
11571161
dividend.buf = digitbuf_alloc(var1->ndigits);
1162+
if (dividend.buf == NULL)
1163+
goto done;
11581164
dividend.digits = dividend.buf;
11591165
memcpy(dividend.digits, var1->digits, var1->ndigits);
11601166

11611167
/*
1162-
* Setup the result
1168+
* Setup the result. Do the allocation in a temporary buffer
1169+
* first, so we don't free result->buf unless we have successfully
1170+
* allocated a buffer to replace it with.
11631171
*/
1172+
tmp_buf = digitbuf_alloc(res_ndigits + 2);
1173+
if (tmp_buf == NULL)
1174+
goto done;
11641175
digitbuf_free(result->buf);
1165-
result->buf = digitbuf_alloc(res_ndigits + 2);
1176+
result->buf = tmp_buf;
11661177
res_digits = result->buf;
11671178
result->digits = res_digits;
11681179
result->ndigits = res_ndigits;
@@ -1201,6 +1212,8 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
12011212

12021213
memcpy(&divisor[guess], &divisor[1], sizeof(numeric));
12031214
divisor[guess].buf = digitbuf_alloc(divisor[guess].ndigits);
1215+
if (divisor[guess].buf == NULL)
1216+
goto done;
12041217
divisor[guess].digits = divisor[guess].buf;
12051218
for (i = divisor[1].ndigits - 1; i >= 0; i--)
12061219
{
@@ -1233,7 +1246,8 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
12331246
if (guess == 0)
12341247
continue;
12351248

1236-
sub_abs(&dividend, &divisor[guess], &dividend);
1249+
if (sub_abs(&dividend, &divisor[guess], &dividend) != 0)
1250+
goto done;
12371251

12381252
first_nextdigit = dividend.weight - weight_tmp;
12391253
first_have = 0;
@@ -1269,15 +1283,23 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
12691283
if (result->ndigits == 0)
12701284
result->sign = NUMERIC_POS;
12711285

1286+
result->dscale = res_dscale;
1287+
err = 0; /* if we've made it this far, return success */
1288+
1289+
done:
12721290
/*
12731291
* Tidy up
12741292
*/
1275-
digitbuf_free(dividend.buf);
1293+
if (dividend.buf != NULL)
1294+
digitbuf_free(dividend.buf);
1295+
12761296
for (i = 1; i < 10; i++)
1277-
digitbuf_free(divisor[i].buf);
1297+
{
1298+
if (divisor[i].buf != NULL)
1299+
digitbuf_free(divisor[i].buf);
1300+
}
12781301

1279-
result->dscale = res_dscale;
1280-
return 0;
1302+
return err;
12811303
}
12821304

12831305

0 commit comments

Comments
 (0)