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

Commit 67a30ebf authored by Lajos Molnar's avatar Lajos Molnar
Browse files

DO NOT MERGE: Add AUtils::isInRange, and use it to detect malformed MPEG4 nal sizes

Bug: 19641538
Change-Id: I5aae3f100846c125decc61eec7cd6563e3f33777
parent 64290793
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef A_UTILS_H_

#define A_UTILS_H_

/* ============================ math templates ============================ */

template<class T>
void ENSURE_UNSIGNED_TYPE() {
    T TYPE_MUST_BE_UNSIGNED[(T)-1 < 0 ? -1 : 0];
}

// needle is in range [hayStart, hayStart + haySize)
template<class T, class U>
inline static bool isInRange(const T &hayStart, const U &haySize, const T &needle) {
    ENSURE_UNSIGNED_TYPE<U>();
    return (T)(hayStart + haySize) >= hayStart && needle >= hayStart && (U)(needle - hayStart) < haySize;
}

// [needleStart, needleStart + needleSize) is in range [hayStart, hayStart + haySize)
template<class T, class U>
inline static bool isInRange(
        const T &hayStart, const U &haySize, const T &needleStart, const U &needleSize) {
    ENSURE_UNSIGNED_TYPE<U>();
    return isInRange(hayStart, haySize, needleStart)
            && (T)(needleStart + needleSize) >= needleStart
            && (U)(needleStart + needleSize - hayStart) <= haySize;
}

#endif  // A_UTILS_H_
+6 −6
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDefs.h>
@@ -209,8 +210,7 @@ status_t MPEG4DataSource::initCheck() const {
ssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) {
    Mutex::Autolock autoLock(mLock);

    if (offset >= mCachedOffset
            && offset + size <= mCachedOffset + mCachedSize) {
    if (isInRange(mCachedOffset, mCachedSize, offset, size)) {
        memcpy(data, &mCache[offset - mCachedOffset], size);
        return size;
    }
@@ -3270,12 +3270,12 @@ status_t MPEG4Source::read(
            size_t dstOffset = 0;

            while (srcOffset < size) {
                bool isMalFormed = (srcOffset + mNALLengthSize > size);
                bool isMalFormed = !isInRange(0u, size, srcOffset, mNALLengthSize);
                size_t nalLength = 0;
                if (!isMalFormed) {
                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
                    srcOffset += mNALLengthSize;
                    isMalFormed = srcOffset + nalLength > size;
                    isMalFormed = !isInRange(0u, size, srcOffset, nalLength);
                }

                if (isMalFormed) {
@@ -3533,12 +3533,12 @@ status_t MPEG4Source::fragmentedRead(
            size_t dstOffset = 0;

            while (srcOffset < size) {
                bool isMalFormed = (srcOffset + mNALLengthSize > size);
                bool isMalFormed = !isInRange(0u, size, srcOffset, mNALLengthSize);
                size_t nalLength = 0;
                if (!isMalFormed) {
                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
                    srcOffset += mNALLengthSize;
                    isMalFormed = srcOffset + nalLength > size;
                    isMalFormed = !isInRange(0u, size, srcOffset, nalLength);
                }

                if (isMalFormed) {
+118 −0
Original line number Diff line number Diff line
/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "Utils_test"

#include <gtest/gtest.h>
#include <utils/String8.h>
#include <utils/Errors.h>
#include <fcntl.h>
#include <unistd.h>

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/Utils.h>

namespace android {

class UtilsTest : public ::testing::Test {
};

TEST_F(UtilsTest, TestMathTemplates) {
    ASSERT_FALSE(isInRange(-43, 86u, -44));
    ASSERT_TRUE(isInRange(-43, 87u, -43));
    ASSERT_TRUE(isInRange(-43, 88u, -1));
    ASSERT_TRUE(isInRange(-43, 89u, 0));
    ASSERT_TRUE(isInRange(-43, 90u, 46));
    ASSERT_FALSE(isInRange(-43, 91u, 48));
    ASSERT_FALSE(isInRange(-43, 92u, 50));

    ASSERT_FALSE(isInRange(43, 86u, 42));
    ASSERT_TRUE(isInRange(43, 87u, 43));
    ASSERT_TRUE(isInRange(43, 88u, 44));
    ASSERT_TRUE(isInRange(43, 89u, 131));
    ASSERT_FALSE(isInRange(43, 90u, 133));
    ASSERT_FALSE(isInRange(43, 91u, 135));

    ASSERT_FALSE(isInRange(43u, 86u, 42u));
    ASSERT_TRUE(isInRange(43u, 85u, 43u));
    ASSERT_TRUE(isInRange(43u, 84u, 44u));
    ASSERT_TRUE(isInRange(43u, 83u, 125u));
    ASSERT_FALSE(isInRange(43u, 82u, 125u));
    ASSERT_FALSE(isInRange(43u, 81u, 125u));

    ASSERT_FALSE(isInRange(-43, ~0u, 43));
    ASSERT_FALSE(isInRange(-43, ~0u, 44));
    ASSERT_FALSE(isInRange(-43, ~0u, ~0));
    ASSERT_FALSE(isInRange(-43, ~0u, 41));
    ASSERT_FALSE(isInRange(-43, ~0u, 40));

    ASSERT_FALSE(isInRange(43u, ~0u, 43u));
    ASSERT_FALSE(isInRange(43u, ~0u, 41u));
    ASSERT_FALSE(isInRange(43u, ~0u, 40u));
    ASSERT_FALSE(isInRange(43u, ~0u, ~0u));

    ASSERT_FALSE(isInRange(-43, 86u, -44, 0u));
    ASSERT_FALSE(isInRange(-43, 86u, -44, 1u));
    ASSERT_FALSE(isInRange(-43, 86u, -44, 2u));
    ASSERT_FALSE(isInRange(-43, 86u, -44, ~0u));
    ASSERT_TRUE(isInRange(-43, 87u, -43, 0u));
    ASSERT_TRUE(isInRange(-43, 87u, -43, 1u));
    ASSERT_TRUE(isInRange(-43, 87u, -43, 86u));
    ASSERT_TRUE(isInRange(-43, 87u, -43, 87u));
    ASSERT_FALSE(isInRange(-43, 87u, -43, 88u));
    ASSERT_FALSE(isInRange(-43, 87u, -43, ~0u));
    ASSERT_TRUE(isInRange(-43, 88u, -1, 0u));
    ASSERT_TRUE(isInRange(-43, 88u, -1, 45u));
    ASSERT_TRUE(isInRange(-43, 88u, -1, 46u));
    ASSERT_FALSE(isInRange(-43, 88u, -1, 47u));
    ASSERT_FALSE(isInRange(-43, 88u, -1, ~3u));
    ASSERT_TRUE(isInRange(-43, 90u, 46, 0u));
    ASSERT_TRUE(isInRange(-43, 90u, 46, 1u));
    ASSERT_FALSE(isInRange(-43, 90u, 46, 2u));
    ASSERT_FALSE(isInRange(-43, 91u, 48, 0u));
    ASSERT_FALSE(isInRange(-43, 91u, 48, 2u));
    ASSERT_FALSE(isInRange(-43, 91u, 48, ~6u));
    ASSERT_FALSE(isInRange(-43, 92u, 50, 0u));
    ASSERT_FALSE(isInRange(-43, 92u, 50, 1u));

    ASSERT_FALSE(isInRange(43u, 86u, 42u, 0u));
    ASSERT_FALSE(isInRange(43u, 86u, 42u, 1u));
    ASSERT_FALSE(isInRange(43u, 86u, 42u, 2u));
    ASSERT_FALSE(isInRange(43u, 86u, 42u, ~0u));
    ASSERT_TRUE(isInRange(43u, 87u, 43u, 0u));
    ASSERT_TRUE(isInRange(43u, 87u, 43u, 1u));
    ASSERT_TRUE(isInRange(43u, 87u, 43u, 86u));
    ASSERT_TRUE(isInRange(43u, 87u, 43u, 87u));
    ASSERT_FALSE(isInRange(43u, 87u, 43u, 88u));
    ASSERT_FALSE(isInRange(43u, 87u, 43u, ~0u));
    ASSERT_TRUE(isInRange(43u, 88u, 60u, 0u));
    ASSERT_TRUE(isInRange(43u, 88u, 60u, 70u));
    ASSERT_TRUE(isInRange(43u, 88u, 60u, 71u));
    ASSERT_FALSE(isInRange(43u, 88u, 60u, 72u));
    ASSERT_FALSE(isInRange(43u, 88u, 60u, ~3u));
    ASSERT_TRUE(isInRange(43u, 90u, 132u, 0u));
    ASSERT_TRUE(isInRange(43u, 90u, 132u, 1u));
    ASSERT_FALSE(isInRange(43u, 90u, 132u, 2u));
    ASSERT_FALSE(isInRange(43u, 91u, 134u, 0u));
    ASSERT_FALSE(isInRange(43u, 91u, 134u, 2u));
    ASSERT_FALSE(isInRange(43u, 91u, 134u, ~6u));
    ASSERT_FALSE(isInRange(43u, 92u, 136u, 0u));
    ASSERT_FALSE(isInRange(43u, 92u, 136u, 1u));
}

} // namespace android