On Fri, 11 Jan 2019 at 01:20, Ben L <bobsayshi...@live.co.uk> wrote:
>
> Hi all,
>
> First time emailing gcc-patches, so I'm sorry if I get any of this wrong or if
> there's obvious errors repeated in my patches. AFAICT I should be sending each
> change individually rather than as one bulk patch, so I'm sorry about the spam
> too.
>
> All of these changes were found by fuzzing libiberty's demanglers over the
> past week, and I have at least one more that it's currently crashing out on
> but I haven't had time to look into why yet.
>
> Obviously since this is my first time emailing I don't have write access to
> commit any of these, so if any are approved then I'd be grateful if you can
> commit them too.
>
> Thanks,
> Ben
>
> --
>
> As a counter example: 8888888888888888888 * 10 = -3344831479658869200, which 
> is
> valid for 64 bit longs, and evidently divisible by 10.
>
> Also safely check that adding the digit won't cause an overflow too.
>
> No testcase provided since one of the previous testcases flagged this issue 
> up.
>
>      * d-demangle.c: Include <limits.h> if available.
>      (LONG_MAX): Define if necessary.
>      (dlang_number): Fix overflow.
>

Thanks, do you have a copyright assignment with the FSF?

Looks like the D demangling bits can just be committed as one patch,
just one nit though.

---
> @@ -206,15 +213,18 @@ dlang_number (const char *mangled, long *ret)
>
>   while (ISDIGIT (*mangled))
>     {
> +      long digit = mangled[0] - '0';
> +      mangled++;
> +
> +      if (*ret > LONG_MAX / 10)
> +       return NULL;
> +
>       (*ret) *= 10;
>
> -      /* If an overflow occured when multiplying by ten, the result
> -        will not be a multiple of ten.  */
> -      if ((*ret % 10) != 0)
> +      if (LONG_MAX - digit < *ret)
>        return NULL;
>
> -      (*ret) += mangled[0] - '0';
> -      mangled++;
> +      (*ret) += digit;
>      }
>
>    if (*mangled == '\0' || *ret < 0)
---

Rather than checking for overflow twice, I think it would be
sufficient to just do:
---
long digit = mangled[0] - '0';

if (*ret > ((LONG_MAX - digit) / 10))
  return NULL;

(*ret) *= 10;
(*ret) += digit;
mangled++;
---

-- 
Iain

Reply via email to