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:

Previous
From: Neil Conway
Date:
Subject: ecpg: check for strdup() failure
Next
From: Fabien COELHO
Date:
Subject: Re: Users/Groups -> Roles