From 4ad989cc38f6cbe2963524ae3ace455c2ee951b4 Mon Sep 17 00:00:00 2001
From: Moxie Marlinspike <moxie@thoughtcrime.org>
Date: Sun, 8 Jan 2017 13:06:11 -0800
Subject: [PATCH] Fix rounded corners bitmap double free

Fixes #4732
// FREEBIE
---
 res/layout/recent_photo_view_item.xml         |  3 +-
 .../components/RecentPhotoViewRail.java       |  5 ++-
 .../securesms/mms/RoundedCorners.java         | 33 +++++++++++--------
 3 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/res/layout/recent_photo_view_item.xml b/res/layout/recent_photo_view_item.xml
index 39214dfc50..a85a38f7e0 100644
--- a/res/layout/recent_photo_view_item.xml
+++ b/res/layout/recent_photo_view_item.xml
@@ -9,7 +9,8 @@
 
     <ImageView android:id="@+id/thumbnail"
                android:layout_width="match_parent"
-               android:layout_height="match_parent"/>
+               android:layout_height="match_parent"
+               android:scaleType="centerCrop"/>
 
 </org.thoughtcrime.securesms.components.SquareFrameLayout>
 
diff --git a/src/org/thoughtcrime/securesms/components/RecentPhotoViewRail.java b/src/org/thoughtcrime/securesms/components/RecentPhotoViewRail.java
index 71617436fe..7cfb44fd84 100644
--- a/src/org/thoughtcrime/securesms/components/RecentPhotoViewRail.java
+++ b/src/org/thoughtcrime/securesms/components/RecentPhotoViewRail.java
@@ -22,6 +22,7 @@ import android.widget.ImageView;
 
 import com.bumptech.glide.Glide;
 import com.bumptech.glide.load.Key;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
 import com.bumptech.glide.signature.MediaStoreSignature;
 
 import org.thoughtcrime.securesms.R;
@@ -77,6 +78,8 @@ public class RecentPhotoViewRail extends FrameLayout implements LoaderManager.Lo
 
   private static class RecentPhotoAdapter extends CursorRecyclerViewAdapter<RecentPhotoAdapter.RecentPhotoViewHolder> {
 
+    private static final String TAG = RecentPhotoAdapter.class.getName();
+
     @NonNull  private final Uri baseUri;
     @Nullable private OnItemClickedListener clickedListener;
 
@@ -112,7 +115,7 @@ public class RecentPhotoViewRail extends FrameLayout implements LoaderManager.Lo
            .fromMediaStore()
            .load(uri)
            .signature(signature)
-           .centerCrop()
+           .diskCacheStrategy(DiskCacheStrategy.NONE)
            .into(viewHolder.imageView);
 
       viewHolder.imageView.setOnClickListener(new OnClickListener() {
diff --git a/src/org/thoughtcrime/securesms/mms/RoundedCorners.java b/src/org/thoughtcrime/securesms/mms/RoundedCorners.java
index 0e777fb102..4b11170104 100644
--- a/src/org/thoughtcrime/securesms/mms/RoundedCorners.java
+++ b/src/org/thoughtcrime/securesms/mms/RoundedCorners.java
@@ -38,19 +38,24 @@ public class RoundedCorners extends BitmapTransformation {
   {
     final Bitmap toRound = crop ? centerCrop(pool, toTransform, outWidth, outHeight)
                                 : fitCenter(pool, toTransform, outWidth, outHeight);
+
     final Bitmap rounded = round(pool, toRound);
-    if (toRound != null && toRound != rounded && !pool.put(toRound)) {
+
+    if (toRound != null && toRound != rounded && toRound != toTransform && !pool.put(toRound)) {
       toRound.recycle();
     }
+
     return rounded;
   }
 
   private Bitmap centerCrop(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
     final Bitmap toReuse     = pool.get(outWidth, outHeight, getSafeConfig(toTransform));
     final Bitmap transformed = TransformationUtils.centerCrop(toReuse, toTransform, outWidth, outHeight);
+
     if (toReuse != null && toReuse != transformed && !pool.put(toReuse)) {
       toReuse.recycle();
     }
+
     return transformed;
   }
 
@@ -63,28 +68,29 @@ public class RoundedCorners extends BitmapTransformation {
       return null;
     }
 
-    final Bitmap result;
-    final Bitmap toReuse = pool.get(toRound.getWidth(), toRound.getHeight(), getSafeConfig(toRound));
-    if (toReuse != null) {
-      result = toReuse;
-    } else {
+    Bitmap result = pool.get(toRound.getWidth(), toRound.getHeight(), getSafeConfig(toRound));
+
+    if (result == null) {
       result = Bitmap.createBitmap(toRound.getWidth(), toRound.getHeight(), getSafeConfig(toRound));
     }
 
-    final Canvas canvas      = new Canvas(result);
-    final Paint  cornerPaint = new Paint();
-    final Paint  shaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+    Canvas canvas = new Canvas(result);
 
-    shaderPaint.setShader(new BitmapShader(toRound, TileMode.CLAMP, TileMode.CLAMP));
-    cornerPaint.setColor(colorHint);
     if (Config.RGB_565.equals(result.getConfig())) {
+      Paint  cornerPaint = new Paint();
+      cornerPaint.setColor(colorHint);
+
       canvas.drawRect(0, 0, radius, radius, cornerPaint);
       canvas.drawRect(0, toRound.getHeight() - radius, radius, toRound.getHeight(), cornerPaint);
       canvas.drawRect(toRound.getWidth() - radius, 0, toRound.getWidth(), radius, cornerPaint);
       canvas.drawRect(toRound.getWidth() - radius, toRound.getHeight() - radius, toRound.getWidth(), toRound.getHeight(), cornerPaint);
     }
+
+    Paint shaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+    shaderPaint.setShader(new BitmapShader(toRound, TileMode.CLAMP, TileMode.CLAMP));
+
     canvas.drawRoundRect(new RectF(0, 0, toRound.getWidth(), toRound.getHeight()), radius, radius, shaderPaint);
-//    Log.w("RoundedCorners", "in was " + toRound.getWidth() + "x" + toRound.getHeight() + ", out to " + result.getWidth() + "x" + result.getHeight());
+
     return result;
   }
 
@@ -92,7 +98,8 @@ public class RoundedCorners extends BitmapTransformation {
     return bitmap.getConfig() != null ? bitmap.getConfig() : Bitmap.Config.ARGB_8888;
   }
 
-  @Override public String getId() {
+  @Override
+  public String getId() {
     return RoundedCorners.class.getCanonicalName();
   }
 }