Revert "Restrict "javascript" and "file" scheme intents"

This reverts commit ca7ecd85ac925ef44dbef327310f2baad13322f2.

Change-Id: I64460956e6243908a6c575eb4d3c7455efc86dff
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d2d9d0f..6d1c822 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -86,6 +86,7 @@
                 <data android:scheme="http" />
                 <data android:scheme="https" />
                 <data android:scheme="about" />
+                <data android:scheme="javascript" />
             </intent-filter>
             <!--  For these schemes where any of these particular MIME types
                   have been supplied, we are a good candidate. -->
@@ -101,6 +102,16 @@
                 <data android:mimeType="application/xhtml+xml"/>
                 <data android:mimeType="application/vnd.wap.xhtml+xml"/>
             </intent-filter>
+            <!-- For viewing saved web archives. -->
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="http" />
+                <data android:scheme="https" />
+                <data android:scheme="file" />
+                <data android:mimeType="application/x-webarchive-xml"/>
+            </intent-filter>
             <!-- Accept inbound NFC URLs at a low priority -->
             <intent-filter android:priority="-101">
                 <action android:name="android.nfc.action.NDEF_DISCOVERED" />
diff --git a/src/com/android/browser/IntentHandler.java b/src/com/android/browser/IntentHandler.java
index fbe7b25..1b8dfc7 100644
--- a/src/com/android/browser/IntentHandler.java
+++ b/src/com/android/browser/IntentHandler.java
@@ -29,7 +29,6 @@
 import android.provider.Browser;
 import android.provider.MediaStore;
 import android.text.TextUtils;
-import android.util.Log;
 import android.util.Patterns;
 
 import com.android.browser.UI.ComboViews;
@@ -38,7 +37,6 @@
 
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.Locale;
 import java.util.Map;
 
 /**
@@ -46,8 +44,6 @@
  */
 public class IntentHandler {
 
-    private static final String TAG = "IntentHandler";
-
     // "source" parameter for Google search suggested by the browser
     final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
     // "source" parameter for Google search from unknown source
@@ -55,19 +51,6 @@
 
     /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
 
-    private static final String[] SCHEME_WHITELIST = {
-        "http",
-        "https",
-        "about",
-    };
-
-    // "file" is handled separately from other schemes and limited to certain directories -
-    // directories which do not support sym/hardlinks, to prevent trickery
-    private static final String[] FILE_WHITELIST = {
-        "/sdcard",
-        "/mnt/sdcard"
-    };
-
     private Activity mActivity;
     private Controller mController;
     private TabControl mTabControl;
@@ -81,12 +64,6 @@
     }
 
     void onNewIntent(Intent intent) {
-        Uri uri = intent.getData();
-        if (uri != null && isForbiddenUri(uri)) {
-            Log.e(TAG, "Aborting intent with forbidden uri, \"" + uri + "\"");
-            return;
-        }
-
         Tab current = mTabControl.getCurrentTab();
         // When a tab is closed on exit, the current tab index is set to -1.
         // Reset before proceed as Browser requires the current tab to be set.
@@ -130,18 +107,33 @@
                 urlData = new UrlData(mSettings.getHomePage());
             }
 
+            // If url is to view private data files, don't allow.
+            Uri uri = intent.getData();
+            if (uri != null && uri.getScheme().toLowerCase().startsWith("file") &&
+                uri.getPath().startsWith(mActivity.getDatabasePath("foo").getParent())) {
+                return;
+            }
+
             if (intent.getBooleanExtra(Browser.EXTRA_CREATE_NEW_TAB, false)
                   || urlData.isPreloaded()) {
                 Tab t = mController.openTab(urlData);
                 return;
             }
             /*
-             * If the URL is already opened, switch to that tab
-             * phone: Reuse tab with same appId
-             * tablet: Open new tab
+             * TODO: Don't allow javascript URIs
+             * 0) If this is a javascript: URI, *always* open a new tab
+             * 1) If the URL is already opened, switch to that tab
+             * 2-phone) Reuse tab with same appId
+             * 2-tablet) Open new tab
              */
             final String appId = intent
                     .getStringExtra(Browser.EXTRA_APPLICATION_ID);
+            if (!TextUtils.isEmpty(urlData.mUrl) &&
+                    urlData.mUrl.startsWith("javascript:")) {
+                // Always open javascript: URIs in new tabs
+                mController.openTab(urlData);
+                return;
+            }
             if (Intent.ACTION_VIEW.equals(action)
                     && (appId != null)
                     && appId.startsWith(mActivity.getPackageName())) {
@@ -322,41 +314,8 @@
         return true;
     }
 
-    private static boolean isForbiddenUri(Uri uri) {
-        String scheme = uri.getScheme();
-        // Allow URIs with no scheme
-        if (scheme == null) {
-            return false;
-        }
-        scheme = scheme.toLowerCase(Locale.US);
-        if ("file".equals(scheme)) {
-            String path = uri.getPath();
-            // Deny file URIs with invalid paths
-            if (path == null) {
-                return true;
-            }
-
-            // Allow file URIs in certain directories
-            for (String allowed : FILE_WHITELIST) {
-                if (path.startsWith(allowed)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        // Allow certain schemes other than file
-        for (String allowed : SCHEME_WHITELIST) {
-            if (allowed.equals(scheme)) {
-                return false;
-            }
-        }
-        // Deny all other schemes
-        return true;
-    }
-
     /**
-     * A UrlData class to abstract how the content will be sent to WebView.
+     * A UrlData class to abstract how the content will be set to WebView.
      * This base class uses loadUrl to show the content.
      */
     static class UrlData {
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index a4d2ce0..dc1944e 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -74,7 +74,9 @@
 import com.android.browser.homepages.HomeProvider;
 import com.android.browser.provider.SnapshotProvider.Snapshots;
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
@@ -103,6 +105,8 @@
     private static final int CAPTURE_DELAY = 100;
     private static final int INITIAL_PROGRESS = 5;
 
+    private static final String RESTRICTED = "<html><body>not allowed</body></html>";
+
     private static Bitmap sDefaultFavicon;
 
     private static Paint sAlphaPaint = new Paint();
@@ -605,7 +609,27 @@
         @Override
         public WebResourceResponse shouldInterceptRequest(WebView view,
                 String url) {
-            return HomeProvider.shouldInterceptRequest(mContext, url);
+            Uri uri = Uri.parse(url);
+            if (uri.getScheme().toLowerCase().equals("file")) {
+                File file = new File(uri.getPath());
+                try {
+                    if (file.getCanonicalPath().startsWith(
+                            mContext.getApplicationContext().getApplicationInfo().dataDir)) {
+                        return new WebResourceResponse("text/html","UTF-8",
+                                new ByteArrayInputStream(RESTRICTED.getBytes("UTF-8")));
+                    }
+                } catch (Exception ex) {
+                    Log.e(LOGTAG, "Bad canonical path" + ex.toString());
+                    try {
+                        return new WebResourceResponse("text/html","UTF-8",
+                                new ByteArrayInputStream(RESTRICTED.getBytes("UTF-8")));
+                    } catch (java.io.UnsupportedEncodingException e) {
+                    }
+                }
+            }
+            WebResourceResponse res = HomeProvider.shouldInterceptRequest(
+                    mContext, url);
+            return res;
         }
 
         @Override