diff options
Diffstat (limited to 'media/jni/android_media_ImageReader.cpp')
-rw-r--r-- | media/jni/android_media_ImageReader.cpp | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp index 36cfb0f..ad7ee7a 100644 --- a/media/jni/android_media_ImageReader.cpp +++ b/media/jni/android_media_ImageReader.cpp @@ -33,6 +33,9 @@ #include <jni.h> #include <JNIHelp.h> +#include <stdint.h> +#include <inttypes.h> + #define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) #define ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID "mNativeContext" @@ -300,6 +303,14 @@ static uint32_t Image_getJpegSize(CpuConsumer::LockedBuffer* buffer) // failed to find size, default to whole buffer if (size == 0) { + /* + * This is a problem because not including the JPEG header + * means that in certain rare situations a regular JPEG blob + * will be misidentified as having a header, in which case + * we will get a garbage size value. + */ + ALOGW("%s: No JPEG header detected, defaulting to size=width=%d", + __FUNCTION__, width); size = width; } @@ -767,11 +778,12 @@ static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, int imgReaderFmt = ctx->getBufferFormat(); int bufFmt = buffer->format; if (imgReaderFmt != bufFmt) { - // Special casing for when producer switches format - if (imgReaderFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && bufFmt == - HAL_PIXEL_FORMAT_YCrCb_420_SP) { - ctx->setBufferFormat(HAL_PIXEL_FORMAT_YCrCb_420_SP); - ALOGV("%s: Overriding NV21 to YUV_420_888.", __FUNCTION__); + // Special casing for when producer switches to a format compatible with flexible YUV + // (HAL_PIXEL_FORMAT_YCbCr_420_888). + if (imgReaderFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && (bufFmt == + HAL_PIXEL_FORMAT_YCrCb_420_SP || bufFmt == HAL_PIXEL_FORMAT_YV12)) { + ctx->setBufferFormat(bufFmt); + ALOGV("%s: Overriding buffer format YUV_420_888 to %x.", __FUNCTION__, bufFmt); } else { // Return the buffer to the queue. consumer->unlockBuffer(*buffer); @@ -847,6 +859,14 @@ static jobject Image_getByteBuffer(JNIEnv* env, jobject thiz, int idx) // Create byteBuffer from native buffer Image_getLockedBufferInfo(env, buffer, idx, &base, &size); + + if (size > static_cast<uint32_t>(INT32_MAX)) { + // Byte buffer have 'int capacity', so check the range + jniThrowExceptionFmt(env, "java/lang/IllegalStateException", + "Size too large for bytebuffer capacity " PRIu32, size); + return NULL; + } + byteBuffer = env->NewDirectByteBuffer(base, size); // TODO: throw dvm exOutOfMemoryError? if ((byteBuffer == NULL) && (env->ExceptionCheck() == false)) { |