From 396412496f9dd8ef0b303a66adeb6a7e5aa32402 Mon Sep 17 00:00:00 2001 From: Zayd Zaari <110066668+zaydzaari@users.noreply.github.com> Date: Mon, 12 Oct 2026 19:34:49 +0000 Subject: [PATCH] fix(rtc): reject date strings ending at the minutes Require the measured separator after RFC date minutes when seconds are absent. Preserve the destination tick on the parse failure and retain the accepted trailing-space and seconds controls. AI-assisted; based on guarded PS5 measurements with controlled input backing storage. --- core/libs/prx/libSceRtc/Export.cpp | 2 +- core/libs/tests/GuestRtc.cpp | 3 +++ docs/dev/debt/libSceRtc.md | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libSceRtc/Export.cpp b/core/libs/prx/libSceRtc/Export.cpp index b0f3a5603..0744be6f8 100644 --- a/core/libs/prx/libSceRtc/Export.cpp +++ b/core/libs/prx/libSceRtc/Export.cpp @@ -286,7 +286,7 @@ bool parseRfc2822DateTime(const char* cursor, RtcDateTime& time, std::int64_t& o ++cursor; if (readDigits(cursor, 2, second) == 0) return false; if (*cursor == ' ' && !parseZone(cursor + 1, offsetMinutes)) return false; - } else if (*cursor != 0 && *cursor != ' ') { + } else if (*cursor != ' ') { return false; } time = makeDateTime(year, month, day, hour, minute, second, 0); diff --git a/core/libs/tests/GuestRtc.cpp b/core/libs/tests/GuestRtc.cpp index d82c887ad..96273f2b7 100644 --- a/core/libs/tests/GuestRtc.cpp +++ b/core/libs/tests/GuestRtc.cpp @@ -262,6 +262,9 @@ int main() { {"Thu, 01 Mar 2024 12:34:56 ", 0, march, 0}, {"Thu, 01 Mar 2024 12:34:567 EST", 0, march, 0}, {"Thu, 01 Mar 2024 12:34 EST", 0, at(2024, 3, 1, 12, 34, 0), 0}, + {"Thu, 29 Feb 2024 12:34", badParse, untouched, 0}, + {"Thu, 01 Mar 2024 12:34", badParse, untouched, 0}, + {"Thu, 29 Feb 2024 12:34 ", 0, at(2024, 2, 29, 12, 34, 0), 0}, {"Thu, 01 Mar 2024 12:34EST", badParse, untouched, 0}, {"Thu, 01 Mar 2024 1:2:3 EST", 0, at(2024, 3, 1, 1, 2, 3), -300}, {"Thu, 01 Mar 2024 26:00:00 GMT", badParse, untouched, 0}, diff --git a/docs/dev/debt/libSceRtc.md b/docs/dev/debt/libSceRtc.md index ec14acea3..868932aa0 100644 --- a/docs/dev/debt/libSceRtc.md +++ b/docs/dev/debt/libSceRtc.md @@ -3,5 +3,6 @@ ### Unknown function info - [sceRtcParseDateTime](../../../core/libs/prx/libSceRtc/Export.cpp) (libSceRtc) - the console's zone name table is only known from the names measured on PS5 firmware 13.60 and 13.42; any other name is assumed to take the military letter offset of its first character, as every measured name outside the table does (`HST`, `MSK`, `XYZ`), so a name the console's table holds but nobody measured gets the wrong offset +- [sceRtcParseDateTime](../../../core/libs/prx/libSceRtc/Export.cpp) (libSceRtc) - a blank zone after seconds is accepted. With fully allocated input storage on PS5 firmware 13.42, the same NUL-terminated text returned `BAD_PARSE` when the byte after its terminator was zero and succeeded when that byte was uppercase `T`. This dependence on storage after the terminator is not modeled; controlled backing-byte measurements on other firmware and title contexts are unavailable. - [sceRtcFormatRFC2822, sceRtcFormatRFC2822LocalTime, sceRtcFormatRFC3339LocalTime](../../../core/libs/prx/libSceRtc/Export.cpp) (libSceRtc) - only shadPS4 (PS4) has bodies. A null tick returns `INVALID_POINTER` like the existing `sceRtcFormatRFC3339`, where shadPS4 formats the current time instead; offsets outside ±1439 minutes return `INVALID_VALUE` like `sceRtcFormatRFC3339`; the local-time variants use the host's offset at the given instant (shadPS4 uses `sceKernelGettimezone`, the current offset) - [sceRtcGetDosTime, sceRtcSetDosTime](../../../core/libs/prx/libSceRtc/Export.cpp) (libSceRtc) - bit layout from shadPS4 (PS4, the standard FAT date/time). A year outside 1980-2107 makes `GetDosTime` return `INVALID_YEAR` after writing 0 for an earlier one and `0xff9fbf7d` (2107-12-31 23:59:58, the largest encodable time) for a later one, and `SetDosTime` decodes the year as the unsigned 7-bit FAT field (1980-2107) without validating the fields, as the disassembly-derived [fpPS4](https://github.com/red-prig/fpPS4) reimplementation of the PS4 library does; not confirmed on a PS5 title, and shadPS4 instead masks out-of-range years into the packed value and sign-extends the 16-bit date