Merge tag 'LA.UM.5.8.r1-02900-8x98.0' into HEAD

"LA.UM.5.8.r1-02900-8x98.0"

* tag 'LA.UM.5.8.r1-02900-8x98.0': (61 commits)
  Fix exception when add group member and rotate screen
  IMS: CallLogs: Dialer requirements for UI 1.8+
  Fix contact name disappear when update
  Fix can copy sim contacts with number more than 40
  Fix StaleDataException when add group in message
  Fix ClassCastException during monkey test
  Fix delete call log screen force close in split mode
  Contacts: Check the state of writing system settings permission.
  Fix group member refresh double problem
  Fix FC when rotate in group edit screen
  Fix FC when add group as reciepients
  Fix unnecessary update command send to sim card
  contacts crashed
  Phone will auto reboot when click message in contact when no video icon display in contact
  Remove "Refresh" menu in quick contacts
  Fix ClassCastException for ContactsFragment
  Contacts: Update config to control presence.
  Fix save contact to wrong sim card
  Contacts: fix the config mechanism for presence
  Fix FC when drag delete call log to split screen
  ...

Change-Id: I83639afd66f23c0117daddf370cff76bee8034fb
diff --git a/src/com/android/contacts/util/ContactPhotoUtils.java b/src/com/android/contacts/util/ContactPhotoUtils.java
index ce691c3..a80af7f 100644
--- a/src/com/android/contacts/util/ContactPhotoUtils.java
+++ b/src/com/android/contacts/util/ContactPhotoUtils.java
@@ -18,19 +18,17 @@
 package com.android.contacts.util;
 
 import android.content.ClipData;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.net.Uri;
-import android.os.Environment;
 import android.provider.MediaStore;
 import android.support.v4.content.FileProvider;
 import android.util.Log;
-
 import com.android.contacts.R;
 import com.google.common.io.Closeables;
-
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -148,7 +146,7 @@
      */
     public static boolean savePhotoFromUriToUri(Context context, Uri inputUri, Uri outputUri,
             boolean deleteAfterSave) {
-        if (inputUri == null || outputUri == null) {
+        if (inputUri == null || outputUri == null || isFilePathAndNotStorage(inputUri)) {
             return false;
         }
         try (FileOutputStream outputStream = context.getContentResolver()
@@ -173,4 +171,20 @@
         }
         return true;
     }
+
+    /**
+     * Returns {@code true} if the {@code inputUri} is a FILE scheme and it does not point to
+     * the storage directory.
+     */
+    private static boolean isFilePathAndNotStorage(Uri inputUri) {
+        if (ContentResolver.SCHEME_FILE.equals(inputUri.getScheme())) {
+            try {
+                File file = new File(inputUri.getPath()).getCanonicalFile();
+                return !file.getCanonicalPath().startsWith("/storage/");
+            } catch (IOException e) {
+                return false;
+            }
+        }
+        return false;
+    }
 }
diff --git a/tests/src/com/android/contacts/util/ContactPhotoUtilsTest.java b/tests/src/com/android/contacts/util/ContactPhotoUtilsTest.java
new file mode 100644
index 0000000..d17b98c
--- /dev/null
+++ b/tests/src/com/android/contacts/util/ContactPhotoUtilsTest.java
@@ -0,0 +1,49 @@
+package com.android.contacts.util;
+
+import android.net.Uri;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Test cases for {@link ContactPhotoUtils}.
+ *
+ * adb shell am instrument -w -e class com.android.contacts.util.ContactPhotoUtilsTest \
+ *   com.android.contacts.tests/android.test.InstrumentationTestRunner
+ */
+@SmallTest
+public class ContactPhotoUtilsTest extends AndroidTestCase {
+
+  private Uri tempUri;
+
+  @Override
+  protected void setUp() throws Exception {
+    tempUri = ContactPhotoUtils.generateTempImageUri(getContext());
+  }
+
+  protected void tearDown() throws Exception {
+    getContext().getContentResolver().delete(tempUri, null, null);
+  }
+
+  public void testFileUriDataPathFails() {
+    String filePath =
+        "file:///data/data/com.android.contacts/shared_prefs/com.android.contacts.xml";
+
+    assertFalse(
+        ContactPhotoUtils.savePhotoFromUriToUri(getContext(), Uri.parse(filePath), tempUri, false));
+  }
+
+  public void testFileUriCanonicalDataPathFails() {
+    String filePath =
+        "file:///storage/../data/data/com.android.contacts/shared_prefs/com.android.contacts.xml";
+
+    assertFalse(
+        ContactPhotoUtils.savePhotoFromUriToUri(getContext(), Uri.parse(filePath), tempUri, false));
+  }
+
+  public void testContentUriInternalPasses() {
+    Uri internal = ContactPhotoUtils.generateTempImageUri(getContext());
+
+    assertTrue(
+        ContactPhotoUtils.savePhotoFromUriToUri(getContext(), internal, tempUri, true));
+  }
+}