Bug 125023 - Regular expression execution affected by console.log
Summary: Regular expression execution affected by console.log
Status: RESOLVED WORKSFORME
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 528+ (Nightly build)
Hardware: Macintosh Intel OS X 10.9
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-11-29 17:09 PST by Caitlin Potter (:caitp)
Modified: 2014-12-17 10:55 PST (History)
7 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Caitlin Potter (:caitp) 2013-11-29 17:09:19 PST
When investigating an AngularJS issue: https://github.com/angular/angular.js/issues/5192 https://github.com/angular/angular.js/pull/5193, weird behaviour is observed on OSX 10.9 + Safari 7 (and also reported to happen on webkit-based browsers on Ubuntu 13.10).

I'm not quite sure how to describe this weird behaviour, but as can be seen from my comments on the bugs, it appears that an assignment to a RegExp match array before a conditional branch is not executed. Several solutions worked:

1) building an array `parts = ['', parts[1], parts[2], parts[3]]`

2) moving the assignment to after the conditional branch

What made it particularly interesting is that, when stepping through expression by expression in the debugger, the problem would not happen (the assignment occurs and the first value of the matches array is cleared correctly), only when it's not "observed" in the debugger does the unexpected behaviour happen. Sort of a quantum mechanics related bug, clearly.

So, maybe it's some sort of race condition where script contexts are executing different statements in parallel for some reason (but I can't think of a good reason why this would happen at all), or some kind of optimization error?

This issue may have been reported before, but because I'm not exactly certain of the cause, I find it difficult to track down similar issues.
Comment 1 Caitlin Potter (:caitp) 2013-11-29 17:21:18 PST
Test case from the issue linked above: http://plnkr.co/edit/4tXYKqp3p5dmiMrmIUNI

Test case incorporating my patch (which moves the assignment operation to after the conditional branch): http://plnkr.co/edit/8NBJCzK8YMIRGNb8cQ2p?p=preview

To observe the weirdness in the first test case, you can try the following:

1) Set a breakpoint in angular-sanitize.js on line 386

2) When breakpoint is triggered (will require reloading the app), examine the `parts` array. The first item will not be the empty string as it was assigned to be

----

Part 2:

1) Now, set a breakpoint on line 381 and reload the app

2) When the line 381 breakpoint is triggered, step through line by line. This time, parts[0] is set to the empty string.
Comment 2 Peter Bacon Darwin 2013-12-03 01:43:36 PST
Here is a minimal reproduction: http://plnkr.co/edit/CvKkFkvga8Pdz7cik3vf?p=preview

The parts[0] = '' seems to be ignored - you get the whole string duplicated
Uncomment the `console.log()` and it then works as expected.
Comment 3 Peter Bacon Darwin 2013-12-03 09:57:31 PST
I am pretty sure that the issue is that the regex has been optimized so that it only actually executes when you first access a property of the resulting matches object.

In our scenario, we write to a property of this object before we have read from it.  At this point the regex has not actually executed.  As soon as we then read from the object, the regex executes and overwrites our original write.
Comment 4 Geoffrey Garen 2013-12-03 11:10:23 PST
I tested <http://plnkr.co/edit/CvKkFkvga8Pdz7cik3vf?p=preview>. With or without console.log commented out, in r160013, I get: ",,Hi there and greetings!,". The test doesn't communicate whether this is a pass or a fail, but I believe, based on reading the description here, that it is a pass.
Comment 5 Brian Burg 2014-12-17 10:55:00 PST
I cannot reproduce the described behavior. Please re-open if you find a test case that reveals incorrect behavior.