Merge branch 'CB-7291'

This commit is contained in:
Ian Clelland 2014-08-26 15:25:41 -04:00
commit 2e3e4ec3b2
7 changed files with 96 additions and 38 deletions

View File

@ -30,7 +30,20 @@
Apache Cordova Team
</author>
<access origin="*"/>
<!-- Allow access to arbitrary URLs in the Cordova WebView. This is a
development mode setting, and should be changed for production. -->
<access origin="http://*/*"/>
<access origin="https://*/*"/>
<!-- Grant certain URLs the ability to launch external applications. This
behaviour is set to match that of Cordova versions before 3.6.0, and
should be reviewed before launching an application in production. It
may be changed in the future. -->
<access origin="tel:*" launch-external="yes"/>
<access origin="geo:*" launch-external="yes"/>
<access origin="mailto:*" launch-external="yes"/>
<access origin="sms:*" launch-external="yes"/>
<access origin="market:*" launch-external="yes"/>
<!-- <content src="http://mysite.com/myapp.html" /> for external pages -->
<content src="index.html" />

View File

@ -58,7 +58,7 @@ public class Config {
Log.e(TAG, "Config was not initialised. Did you forget to Config.init(this)?");
return;
}
parser.getWhitelist().addWhiteListEntry(origin, subdomains);
parser.getInternalWhitelist().addWhiteListEntry(origin, subdomains);
}
/**
@ -72,7 +72,21 @@ public class Config {
Log.e(TAG, "Config was not initialised. Did you forget to Config.init(this)?");
return false;
}
return parser.getWhitelist().isUrlWhiteListed(url);
return parser.getInternalWhitelist().isUrlWhiteListed(url);
}
/**
* Determine if URL is in approved list of URLs to launch external applications.
*
* @param url
* @return true if whitelisted
*/
public static boolean isUrlExternallyWhiteListed(String url) {
if (parser == null) {
Log.e(TAG, "Config was not initialised. Did you forget to Config.init(this)?");
return false;
}
return parser.getExternalWhitelist().isUrlWhiteListed(url);
}
public static String getStartUrl() {
@ -87,7 +101,11 @@ public class Config {
}
public static Whitelist getWhitelist() {
return parser.getWhitelist();
return parser.getInternalWhitelist();
}
public static Whitelist getExternalWhitelist() {
return parser.getExternalWhitelist();
}
public static List<PluginEntry> getPluginEntries() {

View File

@ -37,11 +37,16 @@ public class ConfigXmlParser {
private String launchUrl = "file:///android_asset/www/index.html";
private CordovaPreferences prefs = new CordovaPreferences();
private Whitelist whitelist = new Whitelist();
private Whitelist internalWhitelist = new Whitelist();
private Whitelist externalWhitelist = new Whitelist();
private ArrayList<PluginEntry> pluginEntries = new ArrayList<PluginEntry>(20);
public Whitelist getWhitelist() {
return whitelist;
public Whitelist getInternalWhitelist() {
return internalWhitelist;
}
public Whitelist getExternalWhitelist() {
return externalWhitelist;
}
public CordovaPreferences getPreferences() {
@ -77,6 +82,11 @@ public class ConfigXmlParser {
boolean insideFeature = false;
ArrayList<String> urlMap = null;
// Add implicitly allowed URLs
internalWhitelist.addWhiteListEntry("file:///*", false);
internalWhitelist.addWhiteListEntry("content:///*", false);
internalWhitelist.addWhiteListEntry("data:*", false);
while (eventType != XmlResourceParser.END_DOCUMENT) {
if (eventType == XmlResourceParser.START_TAG) {
String strNode = xml.getName();
@ -104,8 +114,21 @@ public class ConfigXmlParser {
else if (strNode.equals("access")) {
String origin = xml.getAttributeValue(null, "origin");
String subdomains = xml.getAttributeValue(null, "subdomains");
boolean external = (xml.getAttributeValue(null, "launch-external") != null);
if (origin != null) {
whitelist.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0));
if (external) {
externalWhitelist.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0));
} else {
if ("*".equals(origin)) {
// Special-case * origin to mean http and https when used for internal
// whitelist. This prevents external urls like sms: and geo: from being
// handled internally.
internalWhitelist.addWhiteListEntry("http://*/*", false);
internalWhitelist.addWhiteListEntry("https://*/*", false);
} else {
internalWhitelist.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0));
}
}
}
}
else if (strNode.equals("preference")) {

View File

@ -130,7 +130,8 @@ public class CordovaActivity extends Activity implements CordovaInterface {
// Read from config.xml:
protected CordovaPreferences preferences;
protected Whitelist whitelist;
protected Whitelist internalWhitelist;
protected Whitelist externalWhitelist;
protected String launchUrl;
protected ArrayList<PluginEntry> pluginEntries;
@ -216,7 +217,8 @@ public class CordovaActivity extends Activity implements CordovaInterface {
preferences = parser.getPreferences();
preferences.setPreferencesBundle(getIntent().getExtras());
preferences.copyIntoIntentExtras(this);
whitelist = parser.getWhitelist();
internalWhitelist = parser.getInternalWhitelist();
externalWhitelist = parser.getExternalWhitelist();
launchUrl = parser.getLaunchUrl();
pluginEntries = parser.getPluginEntries();
Config.parser = parser;
@ -324,7 +326,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
if (appView.pluginManager == null) {
appView.init(this, webViewClient != null ? webViewClient : makeWebViewClient(appView),
webChromeClient != null ? webChromeClient : makeChromeClient(appView),
pluginEntries, whitelist, preferences);
pluginEntries, internalWhitelist, externalWhitelist, preferences);
}
// TODO: Have the views set this themselves.
@ -789,7 +791,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
// If errorUrl specified, then load it
final String errorUrl = preferences.getString("errorUrl", null);
if ((errorUrl != null) && (errorUrl.startsWith("file://") || whitelist.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) {
if ((errorUrl != null) && (errorUrl.startsWith("file://") || internalWhitelist.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) {
// Load URL on UI thread
me.runOnUiThread(new Runnable() {
@ -849,7 +851,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
*/
@Deprecated // Use whitelist object directly.
public boolean isUrlWhiteListed(String url) {
return whitelist.isUrlWhiteListed(url);
return internalWhitelist.isUrlWhiteListed(url);
}
/*

View File

@ -48,18 +48,11 @@ class CordovaUriHelper {
*/
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
boolean shouldOverrideUrlLoading(WebView view, String url) {
// The WebView should support http and https when going on the Internet
if(url.startsWith("http:") || url.startsWith("https:"))
{
// We only need to whitelist sites on the Internet!
if(appView.getWhitelist().isUrlWhiteListed(url))
{
return false;
}
}
// Give plugins the chance to handle the url
else if (this.appView.pluginManager.onOverrideUrlLoading(url)) {
if (this.appView.pluginManager.onOverrideUrlLoading(url)) {
// Do nothing other than what the plugins wanted.
// If any returned true, then the request was handled.
return true;
}
else if(url.startsWith("file://") | url.startsWith("data:"))
{
@ -67,7 +60,11 @@ class CordovaUriHelper {
//DON'T CHANGE THIS UNLESS YOU KNOW WHAT YOU'RE DOING!
return url.contains("app_webview");
}
else
else if (appView.getWhitelist().isUrlWhiteListed(url)) {
// Allow internal navigation
return false;
}
else if (appView.getExternalWhitelist().isUrlWhiteListed(url))
{
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
@ -78,11 +75,12 @@ class CordovaUriHelper {
intent.setSelector(null);
}
this.cordova.getActivity().startActivity(intent);
return true;
} catch (android.content.ActivityNotFoundException e) {
LOG.e(TAG, "Error loading url " + url, e);
}
}
//Default behaviour should be to load the default intent, let's see what happens!
// Intercept the request and do nothing with it -- block it
return true;
}
}

View File

@ -88,7 +88,9 @@ public class CordovaWebView extends WebView {
private WebChromeClient.CustomViewCallback mCustomViewCallback;
private CordovaResourceApi resourceApi;
private Whitelist whitelist;
private Whitelist internalWhitelist;
private Whitelist externalWhitelist;
// The URL passed to loadUrl(), not necessarily the URL of the current page.
String loadedUrl;
private CordovaPreferences preferences;
@ -135,14 +137,16 @@ public class CordovaWebView extends WebView {
// Use two-phase init so that the control will work with XML layouts.
public void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient,
List<PluginEntry> pluginEntries, Whitelist whitelist, CordovaPreferences preferences) {
List<PluginEntry> pluginEntries, Whitelist internalWhitelist, Whitelist externalWhitelist,
CordovaPreferences preferences) {
if (this.cordova != null) {
throw new IllegalStateException();
}
this.cordova = cordova;
this.viewClient = webViewClient;
this.chromeClient = webChromeClient;
this.whitelist = whitelist;
this.internalWhitelist = internalWhitelist;
this.externalWhitelist = externalWhitelist;
this.preferences = preferences;
super.setWebChromeClient(webChromeClient);
super.setWebViewClient(webViewClient);
@ -165,7 +169,7 @@ public class CordovaWebView extends WebView {
if (!Config.isInitialized()) {
Config.init(cdv.getActivity());
}
init(cdv, makeWebViewClient(cdv), makeWebChromeClient(cdv), Config.getPluginEntries(), Config.getWhitelist(), Config.getPreferences());
init(cdv, makeWebViewClient(cdv), makeWebChromeClient(cdv), Config.getPluginEntries(), Config.getWhitelist(), Config.getExternalWhitelist(), Config.getPreferences());
}
}
@ -319,7 +323,11 @@ public class CordovaWebView extends WebView {
public Whitelist getWhitelist() {
return this.whitelist;
return this.internalWhitelist;
}
public Whitelist getExternalWhitelist() {
return this.externalWhitelist;
}
/**
@ -427,7 +435,7 @@ public class CordovaWebView extends WebView {
if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) {
LOG.d(TAG, ">>> loadUrlNow()");
}
if (url.startsWith("file://") || url.startsWith("javascript:") || whitelist.isUrlWhiteListed(url)) {
if (url.startsWith("file://") || url.startsWith("javascript:") || internalWhitelist.isUrlWhiteListed(url)) {
super.loadUrl(url);
}
}
@ -560,7 +568,7 @@ public class CordovaWebView extends WebView {
if (!openExternal) {
// Make sure url is in whitelist
if (url.startsWith("file://") || whitelist.isUrlWhiteListed(url)) {
if (url.startsWith("file://") || internalWhitelist.isUrlWhiteListed(url)) {
// TODO: What about params?
// Load new URL
this.loadUrl(url);

View File

@ -98,10 +98,6 @@ public class Whitelist {
public Whitelist() {
this.whiteList = new ArrayList<URLPattern>();
// Add implicitly allowed URLs
addWhiteListEntry("file:///*", false);
addWhiteListEntry("content:///*", false);
addWhiteListEntry("data:*", false);
}
/* Match patterns (from http://developer.chrome.com/extensions/match_patterns.html)