[ 
https://issues.apache.org/jira/browse/CB-1318?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13445564#comment-13445564
 ] 

Jimmy Jarvis commented on CB-1318:
----------------------------------

This seems like a pretty critical bug as it's difficult to detect and resolve 
for anyone without a deep understanding asynchronous logic design. I'd proposed 
we try and get this fix in and tested as soon as possible. The community of 
users could be experiencing instability in their code without realizing it or 
an easy way to reproduce it because of callback latency, especially in network 
calls.

The problem is that the current callback logic in 2.0.0 enables native code to 
execute incorrect logic across a page reload. The proposed fix insures native 
callbacks cannot survive page reloads. Here is a scenario that demonstrates the 
problem which could be quite common:

1. HTML/JS: Calls native code (gets assigned callbackId = Service1)

2. ------ NATIVE CODE: Begins working on the request (e.g. REST call, which 
will take 2 - 5 seconds)

3. HTML/JS: Page refreshes or navigates to a new page. This causes the 
callbackId to reset to zero and all entries in the callbacks array to be 
cleared (Service1 from Step 1 and pending in Step 2 is now gone)

4. HTML/JS: Calls a different native function (e.g. REST call, Camera, etc. and 
is assigned Service1 again)

5. ------ NATIVE CODE: Completes pending REST call and makes asynchronous 
callback to JS using it's callbackId = Service1

6. HTML/JS: Finds the new page's Service1 callbackId in the callbacks array and 
executes its completion routine, NOT the original REST call's completion 
routine.

                
> Cordova Callback Logic Not Implemented Correctly -  Native Asynchronous 
> Completion Can Call Wrong Logic in Javascript - Requires Non-recurring Unique 
> ID as Outlined
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CB-1318
>                 URL: https://issues.apache.org/jira/browse/CB-1318
>             Project: Apache Cordova
>          Issue Type: Bug
>          Components: iOS
>    Affects Versions: 2.0.0
>            Reporter: Jimmy Jarvis
>            Assignee: Shazron Abdullah
>            Priority: Critical
>             Fix For: 2.2.0
>
>   Original Estimate: 1h
>  Remaining Estimate: 1h
>
> This bug creates very difficult to find execution anomalies for any 
> asynchronous callback that occurs when the calling context has changed.
> PROBLEM: Cordova callback logic can trigger the callback function of an 
> unrelated call from a different context. When a call from Javascript is made, 
> Cordova generates a new callbackId, adds it to the cordova.callbacks array, 
> and passes it along to the native code. Some time later, when the native code 
> completes the request, it injects javascript to call the callbackSuccess or 
> callbackError function. The respective callback handler looks up the callback 
> attributes from the cordova.callbacks array and executes the original 
> caller's completion function. The problem is each page, or reload of a page, 
> resets the callbackId counter to zero and new calls end up reusing the same 
> callbackId, even though the native code haS not yet completed the prior 
> request. This can occur upon a new page load or reload upon an empty href in 
> an anchor tag. A call to native code from page1.html could trigger the 
> completion routine on page2.html because the native code has no context of 
> the change on the other side of the bridge.
> SOLUTION: Replace the incrementing callbackId with a unique identifier to 
> insure only the caller's completion logic will be called. I have done this 
> with a Pseudo-GUID generator. Fix outlined below:
> // REPLACE THIS LINE in both cordova.2.0.0.js and cordova.ios.js
>         callbackId = service + cordova.callbackId++;    // BUG: incrementing 
> Id's can call unrelated callback logic
> // WITH THIS LINE
>         callbackId = service + ":" + 
> 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {var r = 
> Math.random()*16|0,v=c=='x'?r:r&0x3|0x8;return v.toString(16);}); // Generate 
> unique callbackID with Pseudo-GUID
> This fix insures no code will execute if the caller's context has changed and 
> is a more well formatted callbackId.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to