Merge "Fix a mismatch in Bitmap_createFromParcel" into sc-dev am: 6a0f27d52f

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16664941

Change-Id: I580cb62d6f806113a16a4913b849d288c64bce0c
This commit is contained in:
John Reck
2022-01-28 18:25:53 +00:00
committed by Automerger Merge Worker

View File

@@ -686,16 +686,14 @@ static binder_status_t readBlob(AParcel* parcel, T inPlaceCallback, U ashmemCall
} }
return data->ptr != nullptr; return data->ptr != nullptr;
})); }));
inPlaceCallback(std::move(data.ptr), data.size); return inPlaceCallback(std::move(data.ptr), data.size);
return STATUS_OK;
} else if (type == BlobType::ASHMEM) { } else if (type == BlobType::ASHMEM) {
int rawFd = -1; int rawFd = -1;
int32_t size = 0; int32_t size = 0;
ON_ERROR_RETURN(AParcel_readInt32(parcel, &size)); ON_ERROR_RETURN(AParcel_readInt32(parcel, &size));
ON_ERROR_RETURN(AParcel_readParcelFileDescriptor(parcel, &rawFd)); ON_ERROR_RETURN(AParcel_readParcelFileDescriptor(parcel, &rawFd));
android::base::unique_fd fd(rawFd); android::base::unique_fd fd(rawFd);
ashmemCallback(std::move(fd), size); return ashmemCallback(std::move(fd), size);
return STATUS_OK;
} else { } else {
// Although the above if/else was "exhaustive" guard against unknown types // Although the above if/else was "exhaustive" guard against unknown types
return STATUS_UNKNOWN_ERROR; return STATUS_UNKNOWN_ERROR;
@@ -768,7 +766,7 @@ static binder_status_t writeBlob(AParcel* parcel, const int32_t size, const void
// framework, we may need to update this maximum size. // framework, we may need to update this maximum size.
static constexpr size_t kMaxColorSpaceSerializedBytes = 80; static constexpr size_t kMaxColorSpaceSerializedBytes = 80;
static constexpr auto RuntimeException = "java/lang/RuntimeException"; static constexpr auto BadParcelableException = "android/os/BadParcelableException";
static bool validateImageInfo(const SkImageInfo& info, int32_t rowBytes) { static bool validateImageInfo(const SkImageInfo& info, int32_t rowBytes) {
// TODO: Can we avoid making a SkBitmap for this? // TODO: Can we avoid making a SkBitmap for this?
@@ -809,7 +807,7 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
kRGB_565_SkColorType != colorType && kRGB_565_SkColorType != colorType &&
kARGB_4444_SkColorType != colorType && kARGB_4444_SkColorType != colorType &&
kAlpha_8_SkColorType != colorType) { kAlpha_8_SkColorType != colorType) {
jniThrowExceptionFmt(env, RuntimeException, jniThrowExceptionFmt(env, BadParcelableException,
"Bitmap_createFromParcel unknown colortype: %d\n", colorType); "Bitmap_createFromParcel unknown colortype: %d\n", colorType);
return NULL; return NULL;
} }
@@ -821,7 +819,7 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
return NULL; return NULL;
} }
if (!Bitmap::computeAllocationSize(rowBytes, height, &allocationSize)) { if (!Bitmap::computeAllocationSize(rowBytes, height, &allocationSize)) {
jniThrowExceptionFmt(env, RuntimeException, jniThrowExceptionFmt(env, BadParcelableException,
"Received bad bitmap size: width=%d, height=%d, rowBytes=%d", width, "Received bad bitmap size: width=%d, height=%d, rowBytes=%d", width,
height, rowBytes); height, rowBytes);
return NULL; return NULL;
@@ -831,13 +829,23 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
p.get(), p.get(),
// In place callback // In place callback
[&](std::unique_ptr<int8_t[]> buffer, int32_t size) { [&](std::unique_ptr<int8_t[]> buffer, int32_t size) {
if (allocationSize > size) {
android_errorWriteLog(0x534e4554, "213169612");
return STATUS_BAD_VALUE;
}
nativeBitmap = Bitmap::allocateHeapBitmap(allocationSize, imageInfo, rowBytes); nativeBitmap = Bitmap::allocateHeapBitmap(allocationSize, imageInfo, rowBytes);
if (nativeBitmap) { if (nativeBitmap) {
memcpy(nativeBitmap->pixels(), buffer.get(), size); memcpy(nativeBitmap->pixels(), buffer.get(), allocationSize);
return STATUS_OK;
} }
return STATUS_NO_MEMORY;
}, },
// Ashmem callback // Ashmem callback
[&](android::base::unique_fd fd, int32_t size) { [&](android::base::unique_fd fd, int32_t size) {
if (allocationSize > size) {
android_errorWriteLog(0x534e4554, "213169612");
return STATUS_BAD_VALUE;
}
int flags = PROT_READ; int flags = PROT_READ;
if (isMutable) { if (isMutable) {
flags |= PROT_WRITE; flags |= PROT_WRITE;
@@ -846,18 +854,21 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
if (addr == MAP_FAILED) { if (addr == MAP_FAILED) {
const int err = errno; const int err = errno;
ALOGW("mmap failed, error %d (%s)", err, strerror(err)); ALOGW("mmap failed, error %d (%s)", err, strerror(err));
return; return STATUS_NO_MEMORY;
} }
nativeBitmap = nativeBitmap =
Bitmap::createFrom(imageInfo, rowBytes, fd.release(), addr, size, !isMutable); Bitmap::createFrom(imageInfo, rowBytes, fd.release(), addr, size, !isMutable);
return STATUS_OK;
}); });
if (error != STATUS_OK) {
if (error != STATUS_OK && error != STATUS_NO_MEMORY) {
// TODO: Stringify the error, see signalExceptionForError in android_util_Binder.cpp // TODO: Stringify the error, see signalExceptionForError in android_util_Binder.cpp
jniThrowExceptionFmt(env, RuntimeException, "Failed to read from Parcel, error=%d", error); jniThrowExceptionFmt(env, BadParcelableException, "Failed to read from Parcel, error=%d",
error);
return nullptr; return nullptr;
} }
if (!nativeBitmap) { if (error == STATUS_NO_MEMORY || !nativeBitmap) {
jniThrowRuntimeException(env, "Could not allocate java pixel ref."); jniThrowRuntimeException(env, "Could not allocate bitmap data.");
return nullptr; return nullptr;
} }