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: Jim Mellander
Subject: Re: Apparent issue with srand() in gawk (Andreas Schwab)
Date: Thu, 12 Jun 2025 10:24:21 -0700

>
> <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]