Fix integer overflow in ToNtpUnits helper
Bug: b/232293787 Change-Id: I7f781ff38a23ae829447e5274ec7f6493de8195d Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/262240 Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Reviewed-by: Emil Lundmark <lndmrk@webrtc.org> Cr-Commit-Position: refs/heads/main@{#36863}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
1f1abd1dcc
commit
f987c78d14
@ -14,6 +14,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "api/units/time_delta.h"
|
||||
#include "rtc_base/numerics/safe_conversions.h"
|
||||
#include "system_wrappers/include/ntp_time.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -35,11 +36,14 @@ inline uint32_t CompactNtp(NtpTime ntp) {
|
||||
uint32_t SaturatedToCompactNtp(TimeDelta delta);
|
||||
|
||||
// Convert interval to the NTP time resolution (1/2^32 seconds ~= 0.2 ns).
|
||||
// For deltas with absolute value larger than 35 minutes result is unspecified.
|
||||
inline constexpr int64_t ToNtpUnits(TimeDelta delta) {
|
||||
// For better precision `delta` is taken with best TimeDelta precision (us),
|
||||
// then multiplaction and conversion to seconds are swapped to avoid float
|
||||
// arithmetic.
|
||||
return (delta.us() * (int64_t{1} << 32)) / 1'000'000;
|
||||
// 2^31 us ~= 35.8 minutes.
|
||||
return (rtc::saturated_cast<int32_t>(delta.us()) * (int64_t{1} << 32)) /
|
||||
1'000'000;
|
||||
}
|
||||
|
||||
// Converts interval from compact ntp (1/2^16 seconds) resolution to TimeDelta.
|
||||
|
@ -9,6 +9,10 @@
|
||||
*/
|
||||
#include "modules/rtp_rtcp/source/time_util.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
#include "api/units/time_delta.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -109,6 +113,16 @@ TEST(TimeUtilTest, ToNtpUnits) {
|
||||
// 1 us ~= 4'294.97 NTP units. ToNtpUnits makes no rounding promises.
|
||||
EXPECT_GE(ToNtpUnits(TimeDelta::Micros(1)), 4'294);
|
||||
EXPECT_LE(ToNtpUnits(TimeDelta::Micros(1)), 4'295);
|
||||
|
||||
// Test near maximum and minimum supported values.
|
||||
static constexpr int64_t k35MinutesInNtpUnits = int64_t{35 * 60} << 32;
|
||||
EXPECT_EQ(ToNtpUnits(TimeDelta::Seconds(35 * 60)), k35MinutesInNtpUnits);
|
||||
EXPECT_EQ(ToNtpUnits(TimeDelta::Seconds(-35 * 60)), -k35MinutesInNtpUnits);
|
||||
|
||||
// The result for too large or too small values is unspecified, but
|
||||
// shouldn't cause integer overflow or other undefined behavior.
|
||||
ToNtpUnits(TimeDelta::Micros(std::numeric_limits<int64_t>::max() - 1));
|
||||
ToNtpUnits(TimeDelta::Micros(std::numeric_limits<int64_t>::min() + 1));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
Reference in New Issue
Block a user