Merge "ACodec.cpp: Removed a null pointer dereference triggered in an ALOGV statement." into nyc-dev
diff --git a/include/media/stagefright/foundation/Mutexed.h b/include/media/stagefright/foundation/Mutexed.h
index e905d86..143b140 100644
--- a/include/media/stagefright/foundation/Mutexed.h
+++ b/include/media/stagefright/foundation/Mutexed.h
@@ -103,6 +103,10 @@
     class Locked {
     public:
         inline Locked(Mutexed<T> &mParent);
+        inline Locked(Locked &&from) :
+            mLock(from.mLock),
+            mTreasure(from.mTreasure),
+            mLocked(from.mLocked) {}
         inline ~Locked();
 
         // dereference the protected structure. This returns nullptr if the
@@ -148,9 +152,9 @@
     // Lock the mutex, and create an accessor-guard (a Locked object) to access the underlying
     // structure. This returns an object that dereferences to the wrapped structure when the mutex
     // is locked by it, or otherwise to "null".
-    inline Locked&& lock() {
-        // use rvalue as Locked has no copy constructor
-        return std::move(Locked(*this));
+    // This is just a shorthand for Locked() constructor to avoid specifying the template type.
+    inline Locked lock() {
+        return Locked(*this);
     }
 
 private:
@@ -169,7 +173,6 @@
       mTreasure(mParent.mTreasure),
       mLocked(true) {
     mLock.lock();
-
 }
 
 template<typename T>
diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp
index 5e0baa4..52688b1 100644
--- a/media/libstagefright/FileSource.cpp
+++ b/media/libstagefright/FileSource.cpp
@@ -57,12 +57,34 @@
       mDrmManagerClient(NULL),
       mDrmBufOffset(0),
       mDrmBufSize(0),
-      mDrmBuf(NULL){
+      mDrmBuf(NULL) {
     ALOGV("fd=%d (%s), offset=%lld, length=%lld",
             fd, nameForFd(fd).c_str(), (long long) offset, (long long) length);
 
-    CHECK(offset >= 0);
-    CHECK(length >= 0);
+    if (mOffset < 0) {
+        mOffset = 0;
+    }
+    if (mLength < 0) {
+        mLength = 0;
+    }
+    if (mLength > INT64_MAX - mOffset) {
+        mLength = INT64_MAX - mOffset;
+    }
+    struct stat s;
+    if (fstat(fd, &s) == 0) {
+        if (mOffset > s.st_size) {
+            mOffset = s.st_size;
+            mLength = 0;
+        }
+        if (mOffset + mLength > s.st_size) {
+            mLength = s.st_size - mOffset;
+        }
+    }
+    if (mOffset != offset || mLength != length) {
+        ALOGW("offset/length adjusted from %lld/%lld to %lld/%lld",
+                (long long) offset, (long long) length,
+                (long long) mOffset, (long long) mLength);
+    }
 }
 
 FileSource::~FileSource() {
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 7240e1a..82e7a26 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -252,6 +252,7 @@
       mDataSource(source),
       mFirstFramePos(-1),
       mFixedHeader(0) {
+
     off64_t pos = 0;
     off64_t post_id3_pos;
     uint32_t header;
@@ -350,7 +351,13 @@
     if (mSeeker == NULL || !mSeeker->getDuration(&durationUs)) {
         off64_t fileSize;
         if (mDataSource->getSize(&fileSize) == OK) {
-            durationUs = 8000LL * (fileSize - mFirstFramePos) / bitrate;
+            off64_t dataLength = fileSize - mFirstFramePos;
+            if (dataLength > INT64_MAX / 8000LL) {
+                // duration would overflow
+                durationUs = INT64_MAX;
+            } else {
+                durationUs = 8000LL * dataLength / bitrate;
+            }
         } else {
             durationUs = -1;
         }