Browse Source

chore: cherry-pick e50772b2a25e from skia (#25245)

Jeremy Rose 4 years ago
parent
commit
6e7425164f

+ 1 - 0
patches/skia/.patches

@@ -1 +1,2 @@
 backport_1080481.patch
+mallocpixelref_should_always_allocate_as_large_as_computebytesize.patch

+ 78 - 0
patches/skia/mallocpixelref_should_always_allocate_as_large_as_computebytesize.patch

@@ -0,0 +1,78 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Mike Reed <[email protected]>
+Date: Mon, 20 Jul 2020 18:12:00 -0400
+Subject: MallocPixelRef should always allocate as large as computeByteSize()
+ says
+
+Bug: 1103827
+Change-Id: I837f92cf10a1a389fe1b0ba55ae1323e7e68f741
+Reviewed-on: https://skia-review.googlesource.com/c/skia/+/304416
+Reviewed-by: Ben Wagner <[email protected]>
+Commit-Queue: Mike Reed <[email protected]>
+(cherry picked from commit c1eb58de32c016eb60e7a46046321ffe351e8222)
+Reviewed-on: https://skia-review.googlesource.com/c/skia/+/308761
+Reviewed-by: Heather Miller <[email protected]>
+
+diff --git a/src/core/SkMallocPixelRef.cpp b/src/core/SkMallocPixelRef.cpp
+index d998029a2be43b0ecd913ef8e7b2a52f419812dd..02fd9c458012f8b8b7982d2fe3c971e585b54ac2 100644
+--- a/src/core/SkMallocPixelRef.cpp
++++ b/src/core/SkMallocPixelRef.cpp
+@@ -30,12 +30,9 @@ sk_sp<SkPixelRef> SkMallocPixelRef::MakeAllocate(const SkImageInfo& info, size_t
+     if (!is_valid(info) || !info.validRowBytes(rowBytes)) {
+         return nullptr;
+     }
+-    size_t size = 0;
+-    if (!info.isEmpty() && rowBytes) {
+-        size = info.computeByteSize(rowBytes);
+-        if (SkImageInfo::ByteSizeOverflowed(size)) {
+-            return nullptr;
+-        }
++    size_t size = info.computeByteSize(rowBytes);
++    if (SkImageInfo::ByteSizeOverflowed(size)) {
++        return nullptr;
+     }
+     void* addr = sk_calloc_canfail(size);
+     if (nullptr == addr) {
+diff --git a/tests/BitmapTest.cpp b/tests/BitmapTest.cpp
+index 94bb5af818c518a1a732679659d85d3ae9d7af26..c9d215cb9b504f0f137ff156cf25950263a0277e 100644
+--- a/tests/BitmapTest.cpp
++++ b/tests/BitmapTest.cpp
+@@ -398,3 +398,38 @@ DEF_TEST(getalphaf, reporter) {
+         }
+     }
+ }
++
++/*  computeByteSize() is documented to return 0 if height is zero, but does not
++ *  special-case width==0, so computeByteSize() can return non-zero for that
++ *  (since it is defined to return (height-1)*rb + ...
++ *
++ *  Test that allocPixels() respects this, and allocates a buffer as large as
++ *  computeByteSize()... even though the bitmap is logicallly empty.
++ */
++DEF_TEST(bitmap_zerowidth_crbug_1103827, reporter) {
++    const size_t big_rb = 1 << 16;
++
++    struct {
++        int width, height;
++        size_t rowbytes, expected_size;
++    } rec[] = {
++        { 2, 0,     big_rb,         0 },    // zero-height means zero-size
++        { 0, 2,     big_rb,    big_rb },    // zero-width is computed normally
++    };
++
++    for (const auto& r : rec) {
++        auto info = SkImageInfo::Make(r.width, r.height,
++                                      kRGBA_8888_SkColorType, kPremul_SkAlphaType);
++        size_t size = info.computeByteSize(r.rowbytes);
++        REPORTER_ASSERT(reporter, size == r.expected_size);
++
++        SkBitmap bm;
++        bm.setInfo(info, r.rowbytes);
++        REPORTER_ASSERT(reporter, size == bm.computeByteSize());
++
++        // Be sure we can actually write to that much memory. If the bitmap underallocated
++        // the buffer, this should trash memory and crash (we hope).
++        bm.allocPixels();
++        sk_bzero(bm.getPixels(), size);
++    }
++}