Bug 1289438: [ogg] P4. Use SaferMultDiv where appropriate. r?gerald draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 27 Jul 2016 17:17:21 +1000
changeset 394313 9af73d489ba890a68528f8a107cde5b7e306c0fc
parent 394312 8ed2f528dfa55af1ed941bdce1348c843c19e791
child 394314 e33e19f751746332c94aa0dd7940f48aeb685ad9
push id24553
push userbmo:jyavenard@mozilla.com
push dateFri, 29 Jul 2016 16:10:03 +0000
reviewersgerald
bugs1289438
milestone50.0a1
Bug 1289438: [ogg] P4. Use SaferMultDiv where appropriate. r?gerald MozReview-Commit-ID: 3AWTGciNj4D
dom/media/ogg/OggCodecState.cpp
--- a/dom/media/ogg/OggCodecState.cpp
+++ b/dom/media/ogg/OggCodecState.cpp
@@ -452,21 +452,19 @@ int64_t TheoraState::StartTime(int64_t g
 }
 
 int64_t
 TheoraState::PacketDuration(ogg_packet* aPacket)
 {
   if (!mActive || mInfo.fps_numerator == 0) {
     return -1;
   }
-  CheckedInt64 t = CheckedInt64(mInfo.fps_denominator) * USECS_PER_S;
-  if (!t.isValid()) {
-    return -1;
-  }
-  return t.value() / mInfo.fps_numerator;
+  CheckedInt64 t =
+    SaferMultDiv(mInfo.fps_denominator, USECS_PER_S, mInfo.fps_numerator);
+  return t.isValid() ? t.value() : -1;
 }
 
 int64_t
 TheoraState::MaxKeyframeOffset()
 {
   // Determine the maximum time in microseconds by which a key frame could
   // offset for the theora bitstream. Theora granulepos encode time as:
   // ((key_frame_number << granule_shift) + frame_offset).
@@ -729,21 +727,18 @@ VorbisState::Time(int64_t granulepos)
 }
 
 int64_t
 VorbisState::Time(vorbis_info* aInfo, int64_t aGranulepos)
 {
   if (aGranulepos == -1 || aInfo->rate == 0) {
     return -1;
   }
-  CheckedInt64 t = CheckedInt64(aGranulepos) * USECS_PER_S;
-  if (!t.isValid()) {
-    t = 0;
-  }
-  return t.value() / aInfo->rate;
+  CheckedInt64 t = SaferMultDiv(aGranulepos, USECS_PER_S, aInfo->rate);
+  return t.isValid() ? t.value() : 0;
 }
 
 int64_t
 VorbisState::PacketDuration(ogg_packet* aPacket)
 {
   if (!mActive) {
     return -1;
   }
@@ -1074,18 +1069,18 @@ OpusState::Time(int64_t aGranulepos)
 int64_t
 OpusState::Time(int aPreSkip, int64_t aGranulepos)
 {
   if (aGranulepos < 0) {
     return -1;
   }
 
   // Ogg Opus always runs at a granule rate of 48 kHz.
-  CheckedInt64 t = (CheckedInt64(aGranulepos) - aPreSkip) * USECS_PER_S;
-  return t.isValid() ? t.value() / 48000 : -1;
+  CheckedInt64 t = SaferMultDiv(aGranulepos - aPreSkip, USECS_PER_S, 48000);
+  return t.isValid() ? t.value() : -1;
 }
 
 bool
 OpusState::IsHeader(ogg_packet* aPacket)
 {
   return aPacket->bytes >= 16 &&
          (!memcmp(aPacket->packet, "OpusHead", 8) ||
           !memcmp(aPacket->packet, "OpusTags", 8));
@@ -1135,18 +1130,18 @@ GetOpusDeltaGP(ogg_packet* packet)
   }
   NS_WARNING("Invalid Opus packet.");
   return nframes;
 }
 
 int64_t
 OpusState::PacketDuration(ogg_packet* aPacket)
 {
-  CheckedInt64 t = CheckedInt64(GetOpusDeltaGP(aPacket)) * USECS_PER_S;
-  return t.isValid() ? t.value() / 48000 : -1;
+  CheckedInt64 t = SaferMultDiv(GetOpusDeltaGP(aPacket), USECS_PER_S, 48000);
+  return t.isValid() ? t.value() : -1;
 }
 
 bool
 OpusState::ReconstructOpusGranulepos(void)
 {
   NS_ASSERTION(mUnstamped.Length() > 0, "Must have unstamped packets");
   ogg_packet* last = mUnstamped[mUnstamped.Length()-1];
   NS_ASSERTION(last->e_o_s || last->granulepos > 0,
@@ -1356,30 +1351,30 @@ SkeletonState::DecodeIndex(ogg_packet* a
   if (timeDenom == 0) {
     LOG(LogLevel::Debug, ("Ogg Skeleton Index packet for stream %u has 0 "
                        "timestamp denominator.", serialno));
     return (mActive = false);
   }
 
   // Extract the start time.
   int64_t timeRawInt = LittleEndian::readInt64(p + INDEX_FIRST_NUMER_OFFSET);
-  CheckedInt64 t = CheckedInt64(timeRawInt) * USECS_PER_S;
+  CheckedInt64 t = SaferMultDiv(timeRawInt, USECS_PER_S, timeDenom);
   if (!t.isValid()) {
     return (mActive = false);
   } else {
-    startTime = t.value() / timeDenom;
+    startTime = t.value();
   }
 
   // Extract the end time.
   timeRawInt = LittleEndian::readInt64(p + INDEX_LAST_NUMER_OFFSET);
-  t = CheckedInt64(timeRawInt) * USECS_PER_S;
+  t = SaferMultDiv(timeRawInt, USECS_PER_S, timeDenom);
   if (!t.isValid()) {
     return (mActive = false);
   } else {
-    endTime = t.value() / timeDenom;
+    endTime = t.value();
   }
 
   // Check the numKeyPoints value read, ensure we're not going to run out of
   // memory while trying to decode the index packet.
   CheckedInt64 minPacketSize =
     (CheckedInt64(numKeyPoints) * MIN_KEY_POINT_SIZE) + INDEX_KEYPOINT_OFFSET;
   if (!minPacketSize.isValid())
   {
@@ -1423,21 +1418,20 @@ SkeletonState::DecodeIndex(ogg_packet* a
     }
     p = ReadVariableLengthInt(p, limit, delta);
     time += delta;
     if (!time.isValid() ||
         time.value() > endTime ||
         time.value() < startTime) {
       return (mActive = false);
     }
-    CheckedInt64 timeUsecs = time * USECS_PER_S;
+    CheckedInt64 timeUsecs = SaferMultDiv(time.value(), USECS_PER_S, timeDenom);
     if (!timeUsecs.isValid()) {
-      return mActive = false;
+      return (mActive = false);
     }
-    timeUsecs /= timeDenom;
     keyPoints->Add(offset.value(), timeUsecs.value());
     numKeyPointsRead++;
   }
 
   int32_t keyPointsRead = keyPoints->Length();
   if (keyPointsRead > 0) {
     mIndex.Put(serialno, keyPoints.forget());
   }