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(&dividend, &divisor[guess], &dividend);
  
  		first_nextdigit = dividend.weight - weight_tmp;
  		first_have = 0;
--- 1246,1253 ----
  		if (guess == 0)
  			continue;
  
! 		if (sub_abs(&dividend, &divisor[guess], &dividend) != 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;
  }
  
  
---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

               http://www.postgresql.org/docs/faq

Reply via email to