@@ -1096,6 +1096,8 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
1096
1096
int stat = 0 ;
1097
1097
int rscale ;
1098
1098
int res_dscale = select_div_scale (var1 , var2 , & rscale );
1099
+ int err = -1 ;
1100
+ NumericDigit * tmp_buf ;
1099
1101
1100
1102
/*
1101
1103
* First of all division by zero check
@@ -1143,6 +1145,8 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
1143
1145
divisor [1 ].rscale = var2 -> ndigits ;
1144
1146
divisor [1 ].sign = NUMERIC_POS ;
1145
1147
divisor [1 ].buf = digitbuf_alloc (ndigits_tmp );
1148
+ if (divisor [1 ].buf == NULL )
1149
+ goto done ;
1146
1150
divisor [1 ].digits = divisor [1 ].buf ;
1147
1151
divisor [1 ].digits [0 ] = 0 ;
1148
1152
memcpy (& (divisor [1 ].digits [1 ]), var2 -> digits , ndigits_tmp - 1 );
@@ -1155,14 +1159,21 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
1155
1159
dividend .rscale = var1 -> ndigits ;
1156
1160
dividend .sign = NUMERIC_POS ;
1157
1161
dividend .buf = digitbuf_alloc (var1 -> ndigits );
1162
+ if (dividend .buf == NULL )
1163
+ goto done ;
1158
1164
dividend .digits = dividend .buf ;
1159
1165
memcpy (dividend .digits , var1 -> digits , var1 -> ndigits );
1160
1166
1161
1167
/*
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.
1163
1171
*/
1172
+ tmp_buf = digitbuf_alloc (res_ndigits + 2 );
1173
+ if (tmp_buf == NULL )
1174
+ goto done ;
1164
1175
digitbuf_free (result -> buf );
1165
- result -> buf = digitbuf_alloc ( res_ndigits + 2 ) ;
1176
+ result -> buf = tmp_buf ;
1166
1177
res_digits = result -> buf ;
1167
1178
result -> digits = res_digits ;
1168
1179
result -> ndigits = res_ndigits ;
@@ -1201,6 +1212,8 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
1201
1212
1202
1213
memcpy (& divisor [guess ], & divisor [1 ], sizeof (numeric ));
1203
1214
divisor [guess ].buf = digitbuf_alloc (divisor [guess ].ndigits );
1215
+ if (divisor [guess ].buf == NULL )
1216
+ goto done ;
1204
1217
divisor [guess ].digits = divisor [guess ].buf ;
1205
1218
for (i = divisor [1 ].ndigits - 1 ; i >= 0 ; i -- )
1206
1219
{
@@ -1233,7 +1246,8 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
1233
1246
if (guess == 0 )
1234
1247
continue ;
1235
1248
1236
- sub_abs (& dividend , & divisor [guess ], & dividend );
1249
+ if (sub_abs (& dividend , & divisor [guess ], & dividend ) != 0 )
1250
+ goto done ;
1237
1251
1238
1252
first_nextdigit = dividend .weight - weight_tmp ;
1239
1253
first_have = 0 ;
@@ -1269,15 +1283,23 @@ PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result)
1269
1283
if (result -> ndigits == 0 )
1270
1284
result -> sign = NUMERIC_POS ;
1271
1285
1286
+ result -> dscale = res_dscale ;
1287
+ err = 0 ; /* if we've made it this far, return success */
1288
+
1289
+ done :
1272
1290
/*
1273
1291
* Tidy up
1274
1292
*/
1275
- digitbuf_free (dividend .buf );
1293
+ if (dividend .buf != NULL )
1294
+ digitbuf_free (dividend .buf );
1295
+
1276
1296
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
+ }
1278
1301
1279
- result -> dscale = res_dscale ;
1280
- return 0 ;
1302
+ return err ;
1281
1303
}
1282
1304
1283
1305
0 commit comments