Update SubscriptionManager API by replacing 'id' & 'idx' with 'index'.
am: 56eaeedbb4

Change-Id: I6ff74db8a3bcc83768418293a4410e1b05daa732
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 5ab5910..22459c4 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -317,11 +317,13 @@
 
         <provider android:name=".datamodel.MmsFileProvider"
                   android:authorities="com.android.messaging.datamodel.MmsFileProvider"
-                  android:grantUriPermissions="true" />
+                  android:grantUriPermissions="true"
+                  android:exported="false" />
 
         <provider android:name=".datamodel.MediaScratchFileProvider"
                   android:authorities="com.android.messaging.datamodel.MediaScratchFileProvider"
-                  android:grantUriPermissions="true" />
+                  android:grantUriPermissions="true"
+                  android:exported="false" />
 
 
         <!-- Action Services -->
diff --git a/jni/GifTranscoder.cpp b/jni/GifTranscoder.cpp
index 6c71013..9169f1b 100644
--- a/jni/GifTranscoder.cpp
+++ b/jni/GifTranscoder.cpp
@@ -144,10 +144,10 @@
     std::vector<GifByteType> srcBuffer(gifIn->SWidth * gifIn->SHeight);
 
     // Buffer for rendering images from the input GIF.
-    std::unique_ptr<ColorARGB> renderBuffer(new ColorARGB[gifIn->SWidth * gifIn->SHeight]);
+    std::unique_ptr<ColorARGB[]> renderBuffer(new ColorARGB[gifIn->SWidth * gifIn->SHeight]);
 
     // Buffer for writing new images to output GIF (one row at a time).
-    std::unique_ptr<GifByteType> dstRowBuffer(new GifByteType[gifOut->SWidth]);
+    std::unique_ptr<GifByteType[]> dstRowBuffer(new GifByteType[gifOut->SWidth]);
 
     // Many GIFs use DISPOSE_DO_NOT to make images draw on top of previous images. They can also
     // use DISPOSE_BACKGROUND to clear the last image region before drawing the next one. We need
@@ -274,6 +274,11 @@
                     // matches what libframesequence (Rastermill) does.
                     if (imageIndex == 0 && gifIn->SColorMap) {
                         if (gcb.TransparentColor == NO_TRANSPARENT_COLOR) {
+                            if (gifIn->SBackGroundColor < 0 ||
+                                gifIn->SBackGroundColor >= gifIn->SColorMap->ColorCount) {
+                                LOGE("SBackGroundColor overflow");
+                                return false;
+                            }
                             GifColorType bgColorIndex =
                                     gifIn->SColorMap->Colors[gifIn->SBackGroundColor];
                             bgColor = gifColorToColorARGB(bgColorIndex);
@@ -379,6 +384,11 @@
     for (int y = 0; y < gifIn->Image.Height; y++) {
         for (int x = 0; x < gifIn->Image.Width; x++) {
             GifByteType colorIndex = *getPixel(rasterBits, gifIn->Image.Width, x, y);
+            if (colorIndex >= colorMap->ColorCount) {
+                LOGE("Color Index %d is out of bounds (count=%d)", colorIndex,
+                    colorMap->ColorCount);
+                return false;
+            }
 
             // This image may be smaller than the GIF's "logical screen"
             int renderX = x + gifIn->Image.Left;
diff --git a/res/xml-mcc302-mnc610/mms_config.xml b/res/xml-mcc302-mnc610/mms_config.xml
index 576b5c1..7c0183e 100644
--- a/res/xml-mcc302-mnc610/mms_config.xml
+++ b/res/xml-mcc302-mnc610/mms_config.xml
@@ -50,6 +50,4 @@
     <!-- Disable SMS to MMS conversion for multiple recipient SMS -->
     <bool name="enableGroupMms">false</bool>
 
-    <!-- Disable the link to the cell broadcast -->
-    <bool name="config_cellBroadcastAppLinks">false</bool>
 </mms_config>
diff --git a/src/com/android/messaging/datamodel/MediaScratchFileProvider.java b/src/com/android/messaging/datamodel/MediaScratchFileProvider.java
index 29ae4f4..a19523f 100644
--- a/src/com/android/messaging/datamodel/MediaScratchFileProvider.java
+++ b/src/com/android/messaging/datamodel/MediaScratchFileProvider.java
@@ -32,6 +32,7 @@
 import com.google.common.annotations.VisibleForTesting;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.List;
 
 /**
@@ -89,8 +90,23 @@
 
     private static File getFileWithExtension(final String path, final String extension) {
         final Context context = Factory.get().getApplicationContext();
-        return new File(getDirectory(context),
+        final File filePath = new File(getDirectory(context),
                 TextUtils.isEmpty(extension) ? path : path + "." + extension);
+
+        try {
+            if (!filePath.getCanonicalPath()
+                    .startsWith(getDirectory(context).getCanonicalPath())) {
+                LogUtil.e(TAG, "getFileWithExtension: path "
+                        + filePath.getCanonicalPath()
+                        + " does not start with "
+                        + getDirectory(context).getCanonicalPath());
+                return null;
+            }
+        } catch (IOException e) {
+            LogUtil.e(TAG, "getFileWithExtension: getCanonicalPath failed ", e);
+            return null;
+        }
+        return filePath;
     }
 
     private static File getDirectory(final Context context) {
diff --git a/src/com/android/messaging/datamodel/MmsFileProvider.java b/src/com/android/messaging/datamodel/MmsFileProvider.java
index 0022630..eb49802 100644
--- a/src/com/android/messaging/datamodel/MmsFileProvider.java
+++ b/src/com/android/messaging/datamodel/MmsFileProvider.java
@@ -18,12 +18,14 @@
 
 import android.content.Context;
 import android.net.Uri;
+import android.text.TextUtils;
 
 import com.android.messaging.Factory;
 import com.android.messaging.util.LogUtil;
 import com.google.common.annotations.VisibleForTesting;
 
 import java.io.File;
+import java.io.IOException;
 
 /**
  * A very simple content provider that can serve mms files from our cache directory.
@@ -60,7 +62,22 @@
 
     private static File getFile(final String path) {
         final Context context = Factory.get().getApplicationContext();
-        return new File(getDirectory(context), path + ".dat");
+        final File filePath = new File(getDirectory(context), path + ".dat");
+
+        try {
+            if (!filePath.getCanonicalPath()
+                    .startsWith(getDirectory(context).getCanonicalPath())) {
+                LogUtil.e(TAG, "getFile: path "
+                        + filePath.getCanonicalPath()
+                        + " does not start with "
+                        + getDirectory(context).getCanonicalPath());
+                return null;
+            }
+        } catch (IOException e) {
+            LogUtil.e(TAG, "getFile: getCanonicalPath failed ", e);
+            return null;
+        }
+        return filePath;
     }
 
     private static File getDirectory(final Context context) {
diff --git a/src/com/android/messaging/ui/mediapicker/DocumentImagePicker.java b/src/com/android/messaging/ui/mediapicker/DocumentImagePicker.java
index 2c36752..bb267da 100644
--- a/src/com/android/messaging/ui/mediapicker/DocumentImagePicker.java
+++ b/src/com/android/messaging/ui/mediapicker/DocumentImagePicker.java
@@ -24,6 +24,8 @@
 import com.android.messaging.Factory;
 import com.android.messaging.datamodel.data.PendingAttachmentData;
 import com.android.messaging.ui.UIIntents;
+import com.android.messaging.util.LogUtil;
+import com.android.messaging.util.FileUtil;
 import com.android.messaging.util.ImageUtils;
 import com.android.messaging.util.SafeAsyncTask;
 
@@ -111,12 +113,23 @@
         new SafeAsyncTask<Void, Void, String>() {
             @Override
             protected String doInBackgroundTimed(final Void... params) {
+                if (FileUtil.isInPrivateDir(documentUri)) {
+                    // hacker sending private app data. Bail out
+                    if (LogUtil.isLoggable(LogUtil.BUGLE_TAG, LogUtil.ERROR)) {
+                        LogUtil.e(LogUtil.BUGLE_TAG, "Aborting attach of private app data ("
+                                + documentUri + ")");
+                    }
+                    return null;
+                }
                 return ImageUtils.getContentType(
                         Factory.get().getApplicationContext().getContentResolver(), documentUri);
             }
 
             @Override
             protected void onPostExecute(final String contentType) {
+                if (contentType == null) {
+                    return;     // bad uri on input
+                }
                 // Ask the listener to create a temporary placeholder item to show the progress.
                 final PendingAttachmentData pendingItem =
                         PendingAttachmentData.createPendingAttachmentData(contentType,