ThomasDickey / original-mawk

bug-reports for mawk (originally on GoogleCode)
http://invisible-island.net/mawk/mawk.html
17 stars 2 forks source link

srand not casting its argument to double #66

Open q3cpma opened 1 year ago

q3cpma commented 1 year ago

I was bewildered after finding that my function

function rand_init()
{
    cmd = "od -An -N4 -tu4 /dev/urandom"
    cmd | getline
    close(cmd)
    srand($1)
}

always seeded with the same value, even when $1 changes everytime. After substituting $1 with $1 + 0, it began working. Both gawk and busybox awk "work" (i.e. convert the argument to int).

The following patch against mawk-1.3.4-20200120 did the trick for me:

diff --git a/bi_funct.c b/bi_funct.c
index 1e8df21..d718dd0 100644
--- a/bi_funct.c
+++ b/bi_funct.c
@@ -798,6 +798,8 @@ bi_srand(CELL *sp)
        c = *sp;
        *sp = cseed;
        cseed = c;
+       if (cseed.type != C_DOUBLE)
+       cast1_to_d(&cseed);
     }

 #ifdef USE_SYSTEM_SRAND
q3cpma commented 1 year ago

I also noticed that since srand does srandom((unsigned)d_to_i(seed)) internally, at least here, that d_to_i does a simple truncation to INT_MAX and that my od command line produce u32, I was often getting the same actual seed. (Neither gawk nor busybox have that problem; maybe by using 64 bit operands, or something).

Using something smarter than d_to_i could be useful. How about using d_to_U for a starter, since the result is cast to unsigned anyway. Something like fmod(seed, Max_Int), maybe?

ThomasDickey commented 1 year ago

maybe - I applied the fix above, will leave this open until addressing the followup comment.

ThomasDickey commented 5 months ago

gawk uses gmp (not srandom/random), while the preferred functions in mawk are arc4random_stir/arc4random. srandom's prototype uses unsigned; arc4random_stir takes no parameter.

(I'm ignoring busybox, because it tries to do far more than it succeeds in anything)