Bug 22595

Summary: Strange Math.random() behavior (firs time almost always returns approx same number)
Product: WebKit Reporter: Dylan <dylanryan>
Component: JavaScriptCoreAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: ap, rik, zwarich
Priority: P2    
Version: 525.x (Safari 3.1)   
Hardware: Mac   
OS: OS X 10.5   

Dylan
Reported 2008-12-02 11:47:44 PST
Math.random() seems to always return a very similar number the first time it is called. This happens both in the browser (a serious problem) and in JSC (less of an issue but easier to test). First, to verify the problem in the browser. Step 1: Set your Safari preferences so that "new windows open with" a blank page Step 2: Quit (you must quit!) Safari. Step 3: Relaunch Safari. Step 4: Enter javascript:alert(Math.random()) into the address bar and press enter Step 5: Note the number it spits out (at least the first 4 or 5 digits) repeat steps 2-5 multiple times (you MUST QUIT between tries). Notice how the numbers are almost identical? The JavaScript shell exhibits the same behavior, and is much easier to test It looks like the first invocation of Math.random() is on a slow increment, changing at 4 or 5 places past the decimal approx. every second. The following bash script shows this nicely [obviously, change if jsc is in a different place on your computer]: #! /bin/bash i=0 while (( i < 500 )) do echo "Math.random();" | /Applications/WebKit.app/Contents/Frameworks/10.5/JavaScriptCore.framework/Resources/jsc ((++i)) done I'd hazard a guess that the first invocation simply returns the current timestamp, modified in some manner, but I have no basis for this other than seeing the numbers change every second. Firefox does NOT exhibit this same behavior. The WebKit nightlies do exhibit the same behavior as Safari, but you have to disable the WebKit start page in order to get a blank page to load.
Attachments
Alexey Proskuryakov
Comment 1 2008-12-04 09:08:12 PST
(In reply to comment #0) > Math.random() seems to always return a very similar number the first time it is > called. Yes, that's correct. Could you please explain why this is a problem? E.g., would a separate API for a cryptographically strong random generator fix the problem for you?
Dylan
Comment 2 2008-12-04 11:07:26 PST
(In reply to comment #1) > (In reply to comment #0) > > Math.random() seems to always return a very similar number the first time it is > > called. > > Yes, that's correct. Could you please explain why this is a problem? E.g., > would a separate API for a cryptographically strong random generator fix the > problem for you? > It doesn't necessarily need to be strong, it just would be nice if the first random number was usable. ALl it would take is for the javascript engine to call into Math.random once when the program is started and ignore the result, that way the first result the user can possibly get is actually usable. For example, I first noticed this because I wanted to use JSC to handle complex math for me in shell scripts because it is much much easier to write javascript code to deal with numbers than bash code. I had reason to use random numbers, and I had to throw the first result out every time because it was not random at all. Also, I'm sure plenty of web pages expect Math.random to be, well, essentially random. If you set your home page to a page that used Math.random (a quick inspection of sourcecode shows that Apple.com uses Math.random for something, not sure what), you'd get the same result every time you re-launch the program whereas the same thing in Firefox and you get a usable result every time. Worse would be if you were embedding javascript core in another program and depending on its results to be usably random. Given that the workaround is as simple a matter of calling the function once and ignoring the result, it seems that that could be easily done in the JavaScript Core itself (or wherever, I am not familiar with the code myself) when it is initialized, so that to anyone using it (on the web, in a shell, or embedded in a different application), the first result they ask for is actually usable, rather than expecting every program that wants random numbers to discover the problem on their own and throw out the first number. Certainly, you'll never get every web page that uses Math.random() to do that just in case they are loaded as the homepage in Safari, there are just too many pages out there!
Oliver Hunt
Comment 3 2009-01-02 07:17:31 PST
Ah, this was fixed by http://trac.webkit.org/changeset/39507 and then fixed better by http://trac.webkit.org/changeset/39510 (yay cryptographically secure!) Niko had rewritten the Math.random and multipart form submission code to share there implementation but in doing so accidentally stopped seeding rand().
Oliver Hunt
Comment 4 2009-01-02 07:21:19 PST
Ah whoops, Alexey has just corrected me, this was a diferent issue, but it's nonetheles corrected by those two patches :D
Note You need to log in before you can comment on or make changes to this bug.