[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);
- Re: Apparent issue with srand() in gawk (Andreas Schwab),
Jim Mellander <=