fix(rtc): reject out-of-range source ticks in date arithmetic
This commit is contained in:
parent
e91eecc402
commit
76b7294f06
|
|
@ -109,6 +109,7 @@ std::int64_t localOffsetSeconds(std::uint64_t utcTick) {
|
|||
|
||||
int addTicks(RtcTick* dst, const RtcTick* src, std::int64_t count, std::int64_t unit) {
|
||||
if (!dst || !src) return SCE_RTC_ERROR_INVALID_POINTER;
|
||||
if (src->tick > MAX_TICK) return SCE_RTC_ERROR_INVALID_VALUE;
|
||||
if (count != 0 && (count > std::numeric_limits<std::int64_t>::max() / unit || count < std::numeric_limits<std::int64_t>::min() / unit)) return SCE_RTC_ERROR_INVALID_VALUE;
|
||||
const std::int64_t delta = count * unit;
|
||||
if (delta < 0 ? src->tick < static_cast<std::uint64_t>(-(delta + 1)) + 1 : MAX_TICK - src->tick < static_cast<std::uint64_t>(delta)) return SCE_RTC_ERROR_INVALID_VALUE;
|
||||
|
|
@ -118,6 +119,7 @@ int addTicks(RtcTick* dst, const RtcTick* src, std::int64_t count, std::int64_t
|
|||
|
||||
int addMonths(RtcTick* dst, const RtcTick* src, std::int64_t months) {
|
||||
if (!dst || !src) return SCE_RTC_ERROR_INVALID_POINTER;
|
||||
if (src->tick > MAX_TICK) return SCE_RTC_ERROR_INVALID_VALUE;
|
||||
RtcDateTime time = fromTick(src->tick);
|
||||
const std::int64_t monthIndex = time.year * 12 + (time.month - 1) + months;
|
||||
const std::int64_t year = monthIndex / 12;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <limits>
|
||||
|
||||
extern "C" {
|
||||
int APS5_VABI sceRtcCheckValid(const RtcDateTime*);
|
||||
|
|
@ -168,6 +169,38 @@ int main() {
|
|||
Require(sceRtcTickAddTicks(&result, &source, 1) == invalidValue);
|
||||
Require(sceRtcTickAddTicks(nullptr, &source, 1) == invalidPointer);
|
||||
|
||||
const std::uint64_t invalidTicks[] = {maxTick + 1, std::numeric_limits<std::uint64_t>::max()};
|
||||
for (std::uint64_t invalidTick : invalidTicks) {
|
||||
source.tick = invalidTick;
|
||||
result.tick = 123;
|
||||
Require(sceRtcTickAddTicks(&result, &source, 0) == invalidValue && result.tick == 123);
|
||||
Require(sceRtcTickAddTicks(&result, &source, 1) == invalidValue && result.tick == 123);
|
||||
Require(sceRtcTickAddTicks(&result, &source, -1) == invalidValue && result.tick == 123);
|
||||
Require(sceRtcTickAddSeconds(&result, &source, 0) == invalidValue && result.tick == 123);
|
||||
Require(sceRtcTickAddDays(&result, &source, -1) == invalidValue && result.tick == 123);
|
||||
Require(sceRtcTickAddMonths(&result, &source, 0) == invalidValue && result.tick == 123);
|
||||
Require(sceRtcTickAddYears(&result, &source, -1) == invalidValue && result.tick == 123);
|
||||
Require(sceRtcTickAddTicks(&source, &source, 0) == invalidValue && source.tick == invalidTick);
|
||||
Require(sceRtcTickAddMonths(&source, &source, -1) == invalidValue && source.tick == invalidTick);
|
||||
Require(sceRtcTickAddTicks(nullptr, &source, 0) == invalidPointer);
|
||||
Require(sceRtcTickAddMonths(nullptr, &source, 0) == invalidPointer);
|
||||
}
|
||||
|
||||
source.tick = maxTick;
|
||||
Require(sceRtcTickAddTicks(&source, &source, 0) == 0 && source.tick == maxTick);
|
||||
Require(sceRtcTickAddTicks(&source, &source, -1) == 0 && source.tick == maxTick - 1);
|
||||
source.tick = maxTick;
|
||||
Require(sceRtcTickAddMonths(&source, &source, 0) == 0 && source.tick == maxTick);
|
||||
Require(sceRtcTickAddYears(&result, &source, -1) == 0);
|
||||
Require(sceRtcSetTick(&converted, &result) == 0 && Equal(converted, RtcDateTime{9998, 12, 31, 23, 59, 59, 999999}));
|
||||
result.tick = 123;
|
||||
Require(sceRtcTickAddMonths(&result, &source, 1) == invalidValue && result.tick == 123);
|
||||
Require(sceRtcTickAddTicks(&result, &source, std::numeric_limits<std::int64_t>::min()) == invalidValue && result.tick == 123);
|
||||
Require(sceRtcTickAddSeconds(&result, &source, std::numeric_limits<std::int64_t>::max()) == invalidValue && result.tick == 123);
|
||||
source.tick = 0;
|
||||
Require(sceRtcTickAddMonths(&source, &source, 0) == 0 && source.tick == 0);
|
||||
Require(sceRtcTickAddMonths(&result, &source, -1) == invalidValue && result.tick == 123);
|
||||
|
||||
RtcTick now{};
|
||||
Require(sceRtcGetCurrentTick(&now) == 0 && now.tick > leapDayTick);
|
||||
RtcTick local{};
|
||||
|
|
|
|||
Loading…
Reference in New Issue