libSceHttp: keep sceHttpUriSweepPath inside srcSize, cite shadPS4

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Adrià Franch 2026-10-06 11:51:26 +02:00
parent e6d0c9c9b0
commit 7db0a80b19
3 changed files with 10 additions and 6 deletions

View File

@ -1,4 +1,3 @@
#include <algorithm>
#include <cctype>
#include <charconv>
#include <cstdint>
@ -260,7 +259,7 @@ int APS5_VABI sceHttpUriSweepPath(char* dst, const char* src, size_t srcSize) {
if (!dst || !src) return ERROR_INVALID_VALUE;
const size_t length = srcSize - 1;
if (src[0] != '/') {
if (length == 0 || src[0] != '/') {
std::memcpy(dst, src, length);
dst[length] = '\0';
return 0;
@ -271,11 +270,11 @@ int APS5_VABI sceHttpUriSweepPath(char* dst, const char* src, size_t srcSize) {
size_t end = 0;
size_t pos = 1;
while (pos < length) {
if (src[pos] == '.' && src[pos + 1] == '/') {
if (src[pos] == '.' && pos + 1 < length && src[pos + 1] == '/') {
pos += 2;
continue;
}
if (src[pos] == '.' && src[pos + 1] == '.' && src[pos + 2] == '/') {
if (src[pos] == '.' && pos + 2 < length && src[pos + 1] == '.' && src[pos + 2] == '/') {
if (end != 0) {
dst[end] = '\0';
end = static_cast<size_t>(std::strrchr(dst, '/') - dst);
@ -285,8 +284,8 @@ int APS5_VABI sceHttpUriSweepPath(char* dst, const char* src, size_t srcSize) {
continue;
}
size_t count = length - pos;
if (const char* slash = std::strchr(src + pos, '/')) {
count = std::min(static_cast<size_t>(slash + 1 - (src + pos)), count);
if (const void* slash = std::memchr(src + pos, '/', length - pos)) {
count = static_cast<size_t>(static_cast<const char*>(slash) + 1 - (src + pos));
}
std::memcpy(dst + end + 1, src + pos, count);
dst[end + 1 + count] = '\0';

View File

@ -217,4 +217,8 @@ int main() {
Require(sweep("/a/..b/.c", "/a/..b/.c"));
Require(sceHttpUriSweepPath(sweptPath, "/a/b/../c", 6) == 0 && Equal(sweptPath, "/a/b/"));
Require(sceHttpUriSweepPath(sweptPath, "/ab/c", 3) == 0 && Equal(sweptPath, "/a"));
Require(sceHttpUriSweepPath(sweptPath, "/a/./b", 5) == 0 && Equal(sweptPath, "/a/."));
Require(sceHttpUriSweepPath(sweptPath, "/a/b/../c", 8) == 0 && Equal(sweptPath, "/a/b/.."));
char sweptByte[2] = {'x', 'x'};
Require(sceHttpUriSweepPath(sweptByte, "/", 1) == 0 && sweptByte[0] == '\0' && sweptByte[1] == 'x');
}

View File

@ -110,6 +110,7 @@ Throughout the project, every function at every stage either **does exactly what
- [sceHttpParseResponseHeader](../../core/libs/prx/libSceHttp/Export.cpp) (libSceHttp) - signature follows [SharpProspero](https://github.com/SvenGDK/SharpProspero/blob/main/src/SharpProspero/Interop/Net/Http.cs); parsing and error codes follow [shadPS4's reverse-engineered PS4 library](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/network/http.cpp), not confirmed on a PS5 title or hardware. Folded values retain their line breaks and whitespace; an empty first line starts the value scan after its line feed. A consumed byte count above `INT_MAX` throws instead of wrapping.
- [sceHttpParseStatusLine](../../core/libs/prx/libSceHttp/src/Parse.cpp) (libSceHttp) - behaviour and error codes follow the [shadPS4](https://github.com/shadps4-emu/shadPS4) reimplementation of the PS4 library, not confirmed on a PS5 title; unlike it, no byte past `lineLen` is read
- [sceHttpUriUnescape](../../core/libs/prx/libSceHttp/src/Uri.cpp) (libSceHttp) - signature follows [SharpProspero](https://github.com/SvenGDK/SharpProspero/blob/main/src/SharpProspero/Interop/Net/Http.cs); percent decoding, invalid sequences and error codes follow [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/network/http.cpp), not confirmed on a PS5 title or hardware. Size includes the final NUL; malformed escapes and `+` remain unchanged, and decoding runs once.
- [sceHttpUriSweepPath](../../core/libs/prx/libSceHttp/src/Uri.cpp) (libSceHttp) - behaviour follows the [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/network/http.cpp) reimplementation of the PS4 library and its tests (including the PS4 SDK example), not confirmed on a PS5 title or hardware. It is not RFC 3986 5.2.4: a path that doesn't start with `/` is copied unchanged and a trailing `.` or `..` without a slash is kept. Unlike shadPS4, nothing at or past `srcSize - 1` is read, and `srcSize == 1` writes only the terminator
- [sceHttpSetResponseHeaderMaxSize, sceHttpRedirectCacheFlush, sceHttpsUnloadCert](../../core/libs/prx/libSceHttp/Export.cpp) (libSceHttp) - signatures follow [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/network/http.cpp) (PS4); no PS5 reference has them
- [sceHttp2GetMemoryPoolStats](../../core/libs/prx/libSceHttp2/Export.cpp) (libSceHttp2) - unknown signature
- [sceNetGetMemoryPoolStats](../../core/libs/prx/libSceNet/Export.cpp) (libSceNet) - unknown signature