diff options
| author | Lajos Molnar <lajos@google.com> | 2015-05-13 17:07:51 +0000 | 
|---|---|---|
| committer | Android Git Automerger <android-git-automerger@android.com> | 2015-05-13 17:07:51 +0000 | 
| commit | 814463259cfc0b3c30535e6cba89a736f56c4a16 (patch) | |
| tree | 4d3c7e3a9b3f102c6e55a4d685271d578cdd2a64 | |
| parent | dce0777a1c82557fc108dfcd9665e06d583780d1 (diff) | |
| parent | 0eb7c79398ef04e457c76f117feef6d7bcbbc684 (diff) | |
| download | frameworks_av-814463259cfc0b3c30535e6cba89a736f56c4a16.zip frameworks_av-814463259cfc0b3c30535e6cba89a736f56c4a16.tar.gz frameworks_av-814463259cfc0b3c30535e6cba89a736f56c4a16.tar.bz2  | |
am 0eb7c793: am b5fbb811: am c8c86c1d: am bcf2becf: am c531d995: am 438217a0: Merge "Add AUtils::isInRange, and use it to detect malformed MPEG4 nal sizes" into lmp-dev
* commit '0eb7c79398ef04e457c76f117feef6d7bcbbc684':
  Add AUtils::isInRange, and use it to detect malformed MPEG4 nal sizes
| -rw-r--r-- | include/media/stagefright/foundation/AUtils.h | 22 | ||||
| -rw-r--r-- | media/libstagefright/MPEG4Extractor.cpp | 12 | ||||
| -rw-r--r-- | media/libstagefright/tests/Utils_test.cpp | 81 | 
3 files changed, 109 insertions, 6 deletions
diff --git a/include/media/stagefright/foundation/AUtils.h b/include/media/stagefright/foundation/AUtils.h index d7ecf50..47444c1 100644 --- a/include/media/stagefright/foundation/AUtils.h +++ b/include/media/stagefright/foundation/AUtils.h @@ -61,6 +61,28 @@ inline static const T &max(const T &a, const T &b) {      return a > b ? a : b;  } +template<class T> +void ENSURE_UNSIGNED_TYPE() { +    T TYPE_MUST_BE_UNSIGNED[(T)-1 < 0 ? -1 : 0] __unused; +} + +// 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; +} +  /* T must be integer type, period must be positive */  template<class T>  inline static T periodicError(const T &val, const T &period) { diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index 5c0afa9..65d8a04 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -33,6 +33,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> @@ -221,8 +222,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;      } @@ -4120,12 +4120,12 @@ status_t MPEG4Source::read(              size_t dstOffset = 0;              while (srcOffset < size) { -                bool isMalFormed = (srcOffset + mNALLengthSize > size); +                bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);                  size_t nalLength = 0;                  if (!isMalFormed) {                      nalLength = parseNALSize(&mSrcBuffer[srcOffset]);                      srcOffset += mNALLengthSize; -                    isMalFormed = srcOffset + nalLength > size; +                    isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength);                  }                  if (isMalFormed) { @@ -4397,12 +4397,12 @@ status_t MPEG4Source::fragmentedRead(              size_t dstOffset = 0;              while (srcOffset < size) { -                bool isMalFormed = (srcOffset + mNALLengthSize > size); +                bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);                  size_t nalLength = 0;                  if (!isMalFormed) {                      nalLength = parseNALSize(&mSrcBuffer[srcOffset]);                      srcOffset += mNALLengthSize; -                    isMalFormed = srcOffset + nalLength > size; +                    isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength);                  }                  if (isMalFormed) { diff --git a/media/libstagefright/tests/Utils_test.cpp b/media/libstagefright/tests/Utils_test.cpp index 5c323c1..c1e663c 100644 --- a/media/libstagefright/tests/Utils_test.cpp +++ b/media/libstagefright/tests/Utils_test.cpp @@ -192,6 +192,87 @@ TEST_F(UtilsTest, TestMathTemplates) {      ASSERT_EQ(max(-4.3, 8.6), 8.6);      ASSERT_EQ(max(8.6, -4.3), 8.6); +    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)); +      ASSERT_EQ(periodicError(124, 100), 24);      ASSERT_EQ(periodicError(288, 100), 12);      ASSERT_EQ(periodicError(-345, 100), 45);  | 
