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

Commit 2b64421f authored by Clément Julliard's avatar Clément Julliard
Browse files

Add preconditions for YUV formats.

Width and height need to be even and > 0 for the calculated dataSize to
be valid.

Test: test app crashes with a meaningful error message instead of an
allocation failure.

Bug: 163175419

Change-Id: Ibcce3e62f89b7d19d64e8a5efe792b35af6ab401
parent 7518e291
Loading
Loading
Loading
Loading
+68 −0
Original line number Diff line number Diff line
@@ -140,6 +140,27 @@ status_t getLockedImageInfo(LockedImage* buffer, int idx,
    fmt = applyFormatOverrides(fmt, containerFormat);
    switch (fmt) {
        case HAL_PIXEL_FORMAT_YCbCr_420_888:
            // Width and height should be multiple of 2. Wrong dataSize would be returned otherwise.
            if (buffer->width % 2 != 0) {
                ALOGE("YCbCr_420_888: width (%d) should be a multiple of 2", buffer->width);
                return BAD_VALUE;
            }

            if (buffer->height % 2 != 0) {
                ALOGE("YCbCr_420_888: height (%d) should be a multiple of 2", buffer->height);
                return BAD_VALUE;
            }

            if (buffer->width <= 0) {
                ALOGE("YCbCr_420_888: width (%d) should be a > 0", buffer->width);
                return BAD_VALUE;
            }

            if (buffer->height <= 0) {
                ALOGE("YCbCr_420_888: height (%d) should be a > 0", buffer->height);
                return BAD_VALUE;
            }

            pData =
                (idx == 0) ?
                    buffer->data :
@@ -160,6 +181,27 @@ status_t getLockedImageInfo(LockedImage* buffer, int idx,
            break;
        // NV21
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
            // Width and height should be multiple of 2. Wrong dataSize would be returned otherwise.
            if (buffer->width % 2 != 0) {
                ALOGE("YCrCb_420_SP: width (%d) should be a multiple of 2", buffer->width);
                return BAD_VALUE;
            }

            if (buffer->height % 2 != 0) {
                ALOGE("YCrCb_420_SP: height (%d) should be a multiple of 2", buffer->height);
                return BAD_VALUE;
            }

            if (buffer->width <= 0) {
                ALOGE("YCrCb_420_SP: width (%d) should be a > 0", buffer->width);
                return BAD_VALUE;
            }

            if (buffer->height <= 0) {
                ALOGE("YCrCb_420_SP: height (%d) should be a > 0", buffer->height);
                return BAD_VALUE;
            }

            cr = buffer->data + (buffer->stride * buffer->height);
            cb = cr + 1;
            // only map until last pixel
@@ -178,6 +220,27 @@ status_t getLockedImageInfo(LockedImage* buffer, int idx,
            rStride = buffer->width;
            break;
        case HAL_PIXEL_FORMAT_YV12:
            // Width and height should be multiple of 2. Wrong dataSize would be returned otherwise.
            if (buffer->width % 2 != 0) {
                ALOGE("YV12: width (%d) should be a multiple of 2", buffer->width);
                return BAD_VALUE;
            }

            if (buffer->height % 2 != 0) {
                ALOGE("YV12: height (%d) should be a multiple of 2", buffer->height);
                return BAD_VALUE;
            }

            if (buffer->width <= 0) {
                ALOGE("YV12: width (%d) should be a > 0", buffer->width);
                return BAD_VALUE;
            }

            if (buffer->height <= 0) {
                ALOGE("YV12: height (%d) should be a > 0", buffer->height);
                return BAD_VALUE;
            }

            // Y and C stride need to be 16 pixel aligned.
            LOG_ALWAYS_FATAL_IF(buffer->stride % 16,
                                "Stride is not 16 pixel aligned %d", buffer->stride);
@@ -344,6 +407,11 @@ status_t lockImageFromBuffer(sp<GraphicBuffer> buffer, uint32_t inUsage,
    int flexFormat = format;
    if (isPossiblyYUV(format)) {
        res = buffer->lockAsyncYCbCr(inUsage, rect, &ycbcr, fenceFd);

        if (res != OK) {
            ALOGW("lockAsyncYCbCr failed with error %d", res);
        }

        pData = ycbcr.y;
        flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
    }