Merge "Fix sanitizer in audioflinger Threads.cpp."
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 104b324..a8b6614 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -441,65 +441,81 @@
         return NULL;
     }
 
-    int64_t duration;
-    int32_t samplerate;
-    if (track->has_elst && mHeaderTimescale != 0 &&
-            track->meta->findInt64(kKeyDuration, &duration) &&
-            track->meta->findInt32(kKeySampleRate, &samplerate)) {
+    [=] {
+        int64_t duration;
+        int32_t samplerate;
+        if (track->has_elst && mHeaderTimescale != 0 &&
+                track->meta->findInt64(kKeyDuration, &duration) &&
+                track->meta->findInt32(kKeySampleRate, &samplerate)) {
 
-        track->has_elst = false;
+            track->has_elst = false;
 
-        if (track->elst_segment_duration > INT64_MAX) {
-            goto editlistoverflow;
+            if (track->elst_segment_duration > INT64_MAX) {
+                return;
+            }
+            int64_t segment_duration = track->elst_segment_duration;
+            int64_t media_time = track->elst_media_time;
+            int64_t halfscale = mHeaderTimescale / 2;
+            ALOGV("segment_duration = %" PRId64 ", media_time = %" PRId64
+                  ", halfscale = %" PRId64 ", timescale = %d",
+                  segment_duration,
+                  media_time,
+                  halfscale,
+                  mHeaderTimescale);
+
+            int64_t delay;
+            // delay = ((media_time * samplerate) + halfscale) / mHeaderTimescale;
+            if (__builtin_mul_overflow(media_time, samplerate, &delay) ||
+                    __builtin_add_overflow(delay, halfscale, &delay) ||
+                    (delay /= mHeaderTimescale, false) ||
+                    delay > INT32_MAX ||
+                    delay < INT32_MIN) {
+                return;
+            }
+            ALOGV("delay = %" PRId64, delay);
+            track->meta->setInt32(kKeyEncoderDelay, delay);
+
+            int64_t scaled_duration;
+            // scaled_duration = duration * mHeaderTimescale;
+            if (__builtin_mul_overflow(duration, mHeaderTimescale, &scaled_duration)) {
+                return;
+            }
+            ALOGV("scaled_duration = %" PRId64, scaled_duration);
+
+            int64_t segment_end;
+            int64_t padding;
+            // padding = scaled_duration - ((segment_duration + media_time) * 1000000);
+            if (__builtin_add_overflow(segment_duration, media_time, &segment_end) ||
+                    __builtin_mul_overflow(segment_end, 1000000, &segment_end) ||
+                    __builtin_sub_overflow(scaled_duration, segment_end, &padding)) {
+                return;
+            }
+            ALOGV("segment_end = %" PRId64 ", padding = %" PRId64, segment_end, padding);
+
+            if (padding < 0) {
+                // track duration from media header (which is what kKeyDuration is) might
+                // be slightly shorter than the segment duration, which would make the
+                // padding negative. Clamp to zero.
+                padding = 0;
+            }
+
+            int64_t paddingsamples;
+            int64_t halfscale_e6;
+            int64_t timescale_e6;
+            // paddingsamples = ((padding * samplerate) + (halfscale * 1000000))
+            //                / (mHeaderTimescale * 1000000);
+            if (__builtin_mul_overflow(padding, samplerate, &paddingsamples) ||
+                    __builtin_mul_overflow(halfscale, 1000000, &halfscale_e6) ||
+                    __builtin_mul_overflow(mHeaderTimescale, 1000000, &timescale_e6) ||
+                    __builtin_add_overflow(paddingsamples, halfscale_e6, &paddingsamples) ||
+                    (paddingsamples /= timescale_e6, false) ||
+                    paddingsamples > INT32_MAX) {
+                return;
+            }
+            ALOGV("paddingsamples = %" PRId64, paddingsamples);
+            track->meta->setInt32(kKeyEncoderPadding, paddingsamples);
         }
-        int64_t segment_duration = track->elst_segment_duration;
-        int64_t media_time = track->elst_media_time;
-        int64_t halfscale = mHeaderTimescale / 2;
-
-        int64_t delay;
-        // delay = ((media_time * samplerate) + halfscale) / mHeaderTimescale;
-        if (__builtin_mul_overflow(media_time, samplerate, &delay) ||
-                __builtin_add_overflow(delay, halfscale, &delay) ||
-                (delay /= mHeaderTimescale, false) ||
-                delay > INT32_MAX ||
-                delay < INT32_MIN) {
-            goto editlistoverflow;
-        }
-        track->meta->setInt32(kKeyEncoderDelay, delay);
-
-        int64_t scaled_duration;
-        // scaled_duration = ((duration * mHeaderTimescale) + 500000) / 1000000;
-        if (__builtin_mul_overflow(duration, mHeaderTimescale, &scaled_duration) ||
-                __builtin_add_overflow(scaled_duration, 500000, &scaled_duration)) {
-            goto editlistoverflow;
-        }
-        scaled_duration /= 1000000;
-
-        int64_t segment_end;
-        int64_t padding;
-        if (__builtin_add_overflow(segment_duration, media_time, &segment_end) ||
-                __builtin_sub_overflow(scaled_duration, segment_end, &padding)) {
-            goto editlistoverflow;
-        }
-
-        if (padding < 0) {
-            // track duration from media header (which is what kKeyDuration is) might
-            // be slightly shorter than the segment duration, which would make the
-            // padding negative. Clamp to zero.
-            padding = 0;
-        }
-
-        int64_t paddingsamples;
-        // paddingsamples = ((padding * samplerate) + halfscale) / mHeaderTimescale;
-        if (__builtin_mul_overflow(padding, samplerate, &paddingsamples) ||
-                __builtin_add_overflow(paddingsamples, halfscale, &paddingsamples) ||
-                (paddingsamples /= mHeaderTimescale, false) ||
-                paddingsamples > INT32_MAX) {
-            goto editlistoverflow;
-        }
-        track->meta->setInt32(kKeyEncoderPadding, paddingsamples);
-    }
-    editlistoverflow:
+    }();
 
     if ((flags & kIncludeExtensiveMetaData)
             && !track->includes_expensive_metadata) {
diff --git a/services/audioflinger/FastMixerDumpState.cpp b/services/audioflinger/FastMixerDumpState.cpp
index 6475f22..2e4fb8c 100644
--- a/services/audioflinger/FastMixerDumpState.cpp
+++ b/services/audioflinger/FastMixerDumpState.cpp
@@ -78,7 +78,12 @@
     uint32_t bounds = mBounds;
     uint32_t newestOpen = bounds & 0xFFFF;
     uint32_t oldestClosed = bounds >> 16;
-    uint32_t n = (newestOpen - oldestClosed) & 0xFFFF;
+
+    //uint32_t n = (newestOpen - oldestClosed) & 0xFFFF;
+    uint32_t n;
+    __builtin_sub_overflow(newestOpen, oldestClosed, &n);
+    n = n & 0xFFFF;
+
     if (n > mSamplingN) {
         ALOGE("too many samples %u", n);
         n = mSamplingN;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 0f25153..fe93367 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1101,11 +1101,12 @@
 
 void AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_t type)
 {
-    for (size_t i = 0; i < mSyncEvents.size(); i++) {
+    for (size_t i = 0; i < mSyncEvents.size();) {
         if (mSyncEvents[i]->type() == type) {
             mSyncEvents[i]->trigger();
             mSyncEvents.removeAt(i);
-            i--;
+        } else {
+            ++i;
         }
     }
 }
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index b417631..7af2e74 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -859,7 +859,7 @@
     }
 
     // check same pending commands with later time stamps and eliminate them
-    for (i = mAudioCommands.size()-1; i >= 0; i--) {
+    for (i = (ssize_t)mAudioCommands.size()-1; i >= 0; i--) {
         sp<AudioCommand> command2 = mAudioCommands[i];
         // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
         if (command2->mTime <= command->mTime) break;