svn commit: r250432 - head/usr.bin/split
Benjamin Kaduk
bjkfbsd at gmail.com
Fri May 10 17:11:27 UTC 2013
On Fri, May 10, 2013 at 12:23 AM, Eitan Adler <eadler at freebsd.org> wrote:
> Modified: head/usr.bin/split/split.c
>
> ==============================================================================
> --- head/usr.bin/split/split.c Fri May 10 03:49:05 2013 (r250431)
> +++ head/usr.bin/split/split.c Fri May 10 04:23:03 2013 (r250432)
> @@ -359,9 +367,19 @@ newfile(void)
> ofd = fileno(stdout);
> }
>
> - /* maxfiles = 26^sufflen, but don't use libm. */
> + if (dflag) {
> + beg = '0';
> + end = '9';
> + }
> + else {
> + beg = 'a';
> + end = 'z';
> + }
> + pattlen = end - beg + 1;
> +
> + /* maxfiles = pattlen^sufflen, but don't use libm. */
> for (maxfiles = 1, i = 0; i < sufflen; i++)
> - if ((maxfiles *= 26) <= 0)
> + if ((maxfiles *= pattlen) <= 0)
>
This check relies on signed integer overflow, which is undefined behavior.
Furthermore, even if one assumes a non-evil compiler and two's complement
representation, this check fails for pattlen == 10.
10**9 is representable as both a signed and unsigned 32-bit integer, but
10**10 overflows both variants and ends up in the positive side of the
signed space.
With a fixed number of bases to be exponentiated here (10 or 26), it would
seem much simpler to do the logarithm manually out-of-band and just
hardcode a check on sufflen (noting that maxfiles is of type long which can
be either 32 or 64 bits).
-Ben
> errx(EX_USAGE, "suffix is too long (max %ld)", i);
>
> if (fnum == maxfiles)
>
More information about the svn-src-all
mailing list