Merge branch 'master' into 4.0.x (Load timeout, bridge secret, content: URI)

Conflicts:
	framework/src/org/apache/cordova/CordovaWebView.java
This commit is contained in:
Andrew Grieve 2014-11-06 15:37:30 -05:00
commit fdef0db87c
3 changed files with 14 additions and 5 deletions

View File

@ -5,7 +5,7 @@ local.properties
/gradlew.bat /gradlew.bat
/gradle /gradle
# Ant builds # Ant builds
ant-built ant-build
ant-gen ant-gen
# Eclipse builds # Eclipse builds
gen gen

View File

@ -123,7 +123,7 @@ public class AndroidWebView extends WebView implements CordovaWebView {
pluginManager = new PluginManager(this, this.cordova, pluginEntries); pluginManager = new PluginManager(this, this.cordova, pluginEntries);
resourceApi = new CordovaResourceApi(this.getContext(), pluginManager); resourceApi = new CordovaResourceApi(this.getContext(), pluginManager);
bridge = new CordovaBridge(pluginManager, new NativeToJsMessageQueue(this, cordova)); bridge = new CordovaBridge(pluginManager, new NativeToJsMessageQueue(this, cordova), this.cordova.getActivity().getPackageName());
pluginManager.addService("App", "org.apache.cordova.CoreAndroid"); pluginManager.addService("App", "org.apache.cordova.CoreAndroid");
initWebViewSettings(); initWebViewSettings();
@ -598,6 +598,9 @@ public class AndroidWebView extends WebView implements CordovaWebView {
public void handleDestroy() public void handleDestroy()
{ {
// Cancel pending timeout timer.
loadUrlTimeout++;
// Send destroy event to JavaScript // Send destroy event to JavaScript
this.loadUrl("javascript:try{cordova.require('cordova/channel').onDestroy.fire();}catch(e){console.log('exception firing destroy event from native');};"); this.loadUrl("javascript:try{cordova.require('cordova/channel').onDestroy.fire();}catch(e){console.log('exception firing destroy event from native');};");

View File

@ -37,10 +37,12 @@ public class CordovaBridge {
private NativeToJsMessageQueue jsMessageQueue; private NativeToJsMessageQueue jsMessageQueue;
private volatile int expectedBridgeSecret = -1; // written by UI thread, read by JS thread. private volatile int expectedBridgeSecret = -1; // written by UI thread, read by JS thread.
private String loadedUrl; private String loadedUrl;
private String appContentUrlPrefix;
public CordovaBridge(PluginManager pluginManager, NativeToJsMessageQueue jsMessageQueue) { public CordovaBridge(PluginManager pluginManager, NativeToJsMessageQueue jsMessageQueue, String packageName) {
this.pluginManager = pluginManager; this.pluginManager = pluginManager;
this.jsMessageQueue = jsMessageQueue; this.jsMessageQueue = jsMessageQueue;
this.appContentUrlPrefix = "content://" + packageName + ".";
} }
public String jsExec(int bridgeSecret, String service, String action, String callbackId, String arguments) throws JSONException, IllegalAccessException { public String jsExec(int bridgeSecret, String service, String action, String callbackId, String arguments) throws JSONException, IllegalAccessException {
@ -97,6 +99,8 @@ public class CordovaBridge {
} }
// Bridge secret wrong and bridge not due to it being from the previous page. // Bridge secret wrong and bridge not due to it being from the previous page.
if (expectedBridgeSecret < 0 || bridgeSecret != expectedBridgeSecret) { if (expectedBridgeSecret < 0 || bridgeSecret != expectedBridgeSecret) {
Log.e(LOG_TAG, "Bridge access attempt with wrong secret token, possibly from malicious code. Disabling exec() bridge!");
clearBridgeSecret();
throw new IllegalAccessException(); throw new IllegalAccessException();
} }
return true; return true;
@ -165,7 +169,9 @@ public class CordovaBridge {
// Protect against random iframes being able to talk through the bridge. // Protect against random iframes being able to talk through the bridge.
// Trust only file URLs and the start URL's domain. // Trust only file URLs and the start URL's domain.
// The extra origin.startsWith("http") is to protect against iframes with data: having "" as origin. // The extra origin.startsWith("http") is to protect against iframes with data: having "" as origin.
if (origin.startsWith("file:") || (origin.startsWith("http") && loadedUrl.startsWith(origin))) { if (origin.startsWith("file:") ||
origin.startsWith(this.appContentUrlPrefix) ||
(origin.startsWith("http") && loadedUrl.startsWith(origin))) {
// Enable the bridge // Enable the bridge
int bridgeMode = Integer.parseInt(defaultValue.substring(9)); int bridgeMode = Integer.parseInt(defaultValue.substring(9));
jsMessageQueue.setBridgeMode(bridgeMode); jsMessageQueue.setBridgeMode(bridgeMode);