diff mbox series

Fix UB in c-format.c (maybe_read_dollar_number) (PR c/89495)

Message ID 20190225225617.GA7611@tucnak
State New
Headers show
Series Fix UB in c-format.c (maybe_read_dollar_number) (PR c/89495) | expand

Commit Message

Jakub Jelinek Feb. 25, 2019, 10:56 p.m. UTC
Hi!

The testcases Martin has added recently that contain precision or width
that doesn't fit into int cause UB in the following routine, as 10 * argnum
or that + (*fcp - '0') can result in signed integer overflow.

The following patch just does the computation in UHWI, which we know is
wider than int (I think we don't support 64-bit int hosts yet).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Or do you prefer computations in unsigned int?

2019-02-25  Jakub Jelinek  <jakub@redhat.com>

	PR c/89495
	* c-format.c (maybe_read_dollar_number): Compute nargnum in
	HOST_WIDE_INT type to avoid overflows and change overflow_flag
	checking.


	Jakub

Comments

Joseph Myers Feb. 25, 2019, 11:41 p.m. UTC | #1
On Mon, 25 Feb 2019, Jakub Jelinek wrote:

> Hi!
> 
> The testcases Martin has added recently that contain precision or width
> that doesn't fit into int cause UB in the following routine, as 10 * argnum
> or that + (*fcp - '0') can result in signed integer overflow.
> 
> The following patch just does the computation in UHWI, which we know is
> wider than int (I think we don't support 64-bit int hosts yet).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

This patch is OK.
diff mbox series

Patch

--- gcc/c-family/c-format.c.jj	2019-01-16 09:35:04.565323073 +0100
+++ gcc/c-family/c-format.c	2019-02-25 16:26:07.872810237 +0100
@@ -1268,9 +1268,9 @@  maybe_read_dollar_number (const char **f
   overflow_flag = 0;
   while (ISDIGIT (*fcp))
     {
-      int nargnum;
-      nargnum = 10 * argnum + (*fcp - '0');
-      if (nargnum < 0 || nargnum / 10 != argnum)
+      HOST_WIDE_INT nargnum
+	= HOST_WIDE_INT_UC (10) * argnum + (*fcp - '0');
+      if ((int) nargnum != nargnum)
 	overflow_flag = 1;
       argnum = nargnum;
       fcp++;