Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec419e0b authored by Leon Scroggins III's avatar Leon Scroggins III Committed by Leon Scroggins
Browse files

Make Bitmap_createFromParcel check the color count.

When reading from the parcel, if the number of colors is invalid, early
exit.

Add two more checks: setInfo must return true, and Parcel::readInplace
must return non-NULL. The former ensures that the previously read values
(width, height, etc) were valid, and the latter checks that the Parcel
had enough data even if the number of colors was reasonable.

Also use an auto-deleter to handle deletion of the SkBitmap.

BUG=19666945

Change-Id: Icbd562d6d1f131a723724883fd31822d337cf5a6
parent 4771577a
Loading
Loading
Loading
Loading
+15 −7
Original line number Original line Diff line number Diff line
@@ -556,24 +556,33 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
        return NULL;
        return NULL;
    }
    }


    SkBitmap* bitmap = new SkBitmap;
    std::unique_ptr<SkBitmap> bitmap(new SkBitmap);


    bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType), rowBytes);
    if (!bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType), rowBytes)) {
        return NULL;
    }


    SkColorTable* ctable = NULL;
    SkColorTable* ctable = NULL;
    if (colorType == kIndex_8_SkColorType) {
    if (colorType == kIndex_8_SkColorType) {
        int count = p->readInt32();
        int count = p->readInt32();
        if (count < 0 || count > 256) {
            // The data is corrupt, since SkColorTable enforces a value between 0 and 256,
            // inclusive.
            return NULL;
        }
        if (count > 0) {
        if (count > 0) {
            size_t size = count * sizeof(SkPMColor);
            size_t size = count * sizeof(SkPMColor);
            const SkPMColor* src = (const SkPMColor*)p->readInplace(size);
            const SkPMColor* src = (const SkPMColor*)p->readInplace(size);
            if (src == NULL) {
                return NULL;
            }
            ctable = new SkColorTable(src, count);
            ctable = new SkColorTable(src, count);
        }
        }
    }
    }


    jbyteArray buffer = GraphicsJNI::allocateJavaPixelRef(env, bitmap, ctable);
    jbyteArray buffer = GraphicsJNI::allocateJavaPixelRef(env, bitmap.get(), ctable);
    if (NULL == buffer) {
    if (NULL == buffer) {
        SkSafeUnref(ctable);
        SkSafeUnref(ctable);
        delete bitmap;
        return NULL;
        return NULL;
    }
    }


@@ -585,7 +594,6 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
    android::status_t status = p->readBlob(size, &blob);
    android::status_t status = p->readBlob(size, &blob);
    if (status) {
    if (status) {
        doThrowRE(env, "Could not read bitmap from parcel blob.");
        doThrowRE(env, "Could not read bitmap from parcel blob.");
        delete bitmap;
        return NULL;
        return NULL;
    }
    }


@@ -595,8 +603,8 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {


    blob.release();
    blob.release();


    return GraphicsJNI::createBitmap(env, bitmap, buffer, getPremulBitmapCreateFlags(isMutable),
    return GraphicsJNI::createBitmap(env, bitmap.release(), buffer,
            NULL, NULL, density);
            getPremulBitmapCreateFlags(isMutable), NULL, NULL, density);
}
}


static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject,
static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject,