@@ -1096,6 +1096,8 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
10961096int stat = 0 ;
10971097int rscale ;
10981098int 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)
11431145divisor [1 ].rscale = var2 -> ndigits ;
11441146divisor [1 ].sign = NUMERIC_POS ;
11451147divisor [1 ].buf = digitbuf_alloc (ndigits_tmp );
1148+ if (divisor [1 ].buf == NULL )
1149+ gotodone ;
11461150divisor [1 ].digits = divisor [1 ].buf ;
11471151divisor [1 ].digits [0 ]= 0 ;
11481152memcpy (& (divisor [1 ].digits [1 ]),var2 -> digits ,ndigits_tmp - 1 );
@@ -1155,14 +1159,21 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
11551159dividend .rscale = var1 -> ndigits ;
11561160dividend .sign = NUMERIC_POS ;
11571161dividend .buf = digitbuf_alloc (var1 -> ndigits );
1162+ if (dividend .buf == NULL )
1163+ gotodone ;
11581164dividend .digits = dividend .buf ;
11591165memcpy (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+ gotodone ;
11641175digitbuf_free (result -> buf );
1165- result -> buf = digitbuf_alloc ( res_ndigits + 2 ) ;
1176+ result -> buf = tmp_buf ;
11661177res_digits = result -> buf ;
11671178result -> digits = res_digits ;
11681179result -> ndigits = res_ndigits ;
@@ -1201,6 +1212,8 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
12011212
12021213memcpy (& divisor [guess ],& divisor [1 ],sizeof (numeric ));
12031214divisor [guess ].buf = digitbuf_alloc (divisor [guess ].ndigits );
1215+ if (divisor [guess ].buf == NULL )
1216+ gotodone ;
12041217divisor [guess ].digits = divisor [guess ].buf ;
12051218for (i = divisor [1 ].ndigits - 1 ;i >=0 ;i -- )
12061219{
@@ -1233,7 +1246,8 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
12331246if (guess == 0 )
12341247continue ;
12351248
1236- sub_abs (& dividend ,& divisor [guess ],& dividend );
1249+ if (sub_abs (& dividend ,& divisor [guess ],& dividend )!= 0 )
1250+ gotodone ;
12371251
12381252first_nextdigit = dividend .weight - weight_tmp ;
12391253first_have = 0 ;
@@ -1269,15 +1283,23 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
12691283if (result -> ndigits == 0 )
12701284result -> 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+
12761296for (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