From d31e283088e63910c53117d2eafc13920c6f44b4 Mon Sep 17 00:00:00 2001 From: ArjenS-LA Date: Sun, 11 Oct 2026 19:44:13 -0700 Subject: [PATCH] fix(libkernel): throw for unsupported directory entry names --- .../File/src/DirectoryDescriptor.cpp | 4 +-- core/libs/tests/GuestDirectoryBuffer.cpp | 27 +++++-------------- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/core/libs/prx/libkernel/File/src/DirectoryDescriptor.cpp b/core/libs/prx/libkernel/File/src/DirectoryDescriptor.cpp index be0f571ff..05868357b 100644 --- a/core/libs/prx/libkernel/File/src/DirectoryDescriptor.cpp +++ b/core/libs/prx/libkernel/File/src/DirectoryDescriptor.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -137,8 +138,7 @@ int ReadDirectoryDescriptor(int fd, char* buf, int nbytes) { while (state.cursor < state.entries.size()) { const auto& [name, type] = state.entries[state.cursor]; if (name.size() > 255) { - if (used == 0) return SCE_KERNEL_ERROR_ENAMETOOLONG; - break; + throw std::runtime_error("Directory entry name exceeds the guest 255-byte limit"); } const std::size_t record = (8 + name.size() + 1 + 3) & ~std::size_t{3}; if (used + record > static_cast(nbytes)) { diff --git a/core/libs/tests/GuestDirectoryBuffer.cpp b/core/libs/tests/GuestDirectoryBuffer.cpp index 6d1e6f4c3..bfd1beb0d 100644 --- a/core/libs/tests/GuestDirectoryBuffer.cpp +++ b/core/libs/tests/GuestDirectoryBuffer.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include extern "C" { @@ -17,9 +18,6 @@ int APS5_VABI sceKernelOpen(const char*, int, std::uint16_t); int APS5_VABI sceKernelClose(int); int APS5_VABI sceKernelGetdents(int, char*, int); int APS5_VABI sceKernelGetdirentries(int, char*, int, std::int64_t*); -int APS5_VABI getdents_nid_postfix(int, char*, int); -int APS5_VABI getdirentries_nid_postfix(int, char*, int, std::int64_t*); -int* APS5_VABI __error_nid_postfix(); } static void Check(bool value, int line) { @@ -82,24 +80,13 @@ static void CheckOversizedName() { const int directory = sceKernelOpen(root.string().c_str(), SCE_KERNEL_O_RDONLY | SCE_KERNEL_O_DIRECTORY, 0); Require(directory >= 0); std::array buffer; - buffer.fill('x'); - Require(sceKernelGetdents(directory, buffer.data(), static_cast(buffer.size())) == 24); - Require(std::strcmp(buffer.data() + 8, ".") == 0); - Require(std::strcmp(buffer.data() + 20, "..") == 0); - Require(std::all_of(buffer.begin() + 24, buffer.end(), [](char byte) { return byte == 'x'; })); - for (int attempt = 0; attempt < 2; ++attempt) { - buffer.fill('x'); - Require(sceKernelGetdents(directory, buffer.data(), static_cast(buffer.size())) == SCE_KERNEL_ERROR_ENAMETOOLONG); - Require(std::all_of(buffer.begin(), buffer.end(), [](char byte) { return byte == 'x'; })); + bool threw = false; + try { + sceKernelGetdents(directory, buffer.data(), static_cast(buffer.size())); + } catch (const std::runtime_error&) { + threw = true; } - *__error_nid_postfix() = 0; - Require(getdents_nid_postfix(directory, buffer.data(), static_cast(buffer.size())) == -1); - Require(*__error_nid_postfix() == 63); - *__error_nid_postfix() = 0; - std::int64_t base = -1; - Require(getdirentries_nid_postfix(directory, buffer.data(), static_cast(buffer.size()), &base) == -1); - Require(*__error_nid_postfix() == 63); - Require(std::all_of(buffer.begin(), buffer.end(), [](char byte) { return byte == 'x'; })); + Require(threw); Require(sceKernelClose(directory) == 0); std::filesystem::remove_all(root); }