bug-gawk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Apparent issue with srand() in gawk (Andreas Schwab)


From: arnold
Subject: Re: Apparent issue with srand() in gawk (Andreas Schwab)
Date: Fri, 13 Jun 2025 09:00:42 -0600
User-agent: Heirloom mailx 12.5 7/5/10

Thanks. I've made this change. It'll be in Git shortly.

Arnold

Jim Mellander <jmellander@gmail.com> wrote:

> >
> > <snip>
> > On Jun 11 2025, Jim Mellander wrote:
> >
> > > Interestingly, if I pull less than 4 bytes from /dev/urandom for a seed
> > (e.g. "od -t u4 -N 3 /dev/urandom") random numbers are generated as
> > expected. Note that all the seeds in the examples above are > 2^31, which
> > could indicate a signed vs unsigned int issue.
> >
> > Values bigger than LONG_MAX overflow when converted from double to an
> > integer, resulting in undefined behaviour.  In your case the resulting
> > seed is always the same number, 2147483647 or 0x7fffffff.
> >
> > --
> > Andreas Schwab, SUSE Labs, schwab@suse.de
> > GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
> > "And now for something completely different."
> >
> >
> Thanks! I found that on 64 bit systems, the same issue occurs with seeds >=
> 2^63. Changing the cast of the input from 'long' to 'unsigned long'
> corrects the issue.
>
> In case gawk is still in use in Y2038 when 32 bit time_t goes negative, I
> made the same change to the default seed from time_t.
>
> Patch follows
>
> --- builtin.c.old 2025-06-11 20:42:05
> +++ builtin.c 2025-06-11 20:42:51
> @@ -1562,12 +1562,12 @@
>   check_args_min_max(nargs, "srand", 0, 1);
>
>   if (nargs == 0)
> - srandom((unsigned int) (save_seed = (long) time((time_t *) 0)));
> + srandom((unsigned int) (save_seed = (unsigned long) time((time_t *) 0)));
>   else {
>   tmp = POP_SCALAR();
>   if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0)
>   lintwarn(_("%s: received non-numeric argument"), "srand");
> - srandom((unsigned int) (save_seed = (long) force_number(tmp)->numbr));
> + srandom((unsigned int) (save_seed = (unsigned long)
> force_number(tmp)->numbr));
>   DEREF(tmp);
>   }
>   return make_number((AWKNUM) ret);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]