From a41c8cc3f84b85ec20c89cfefc4dead9352e4732 Mon Sep 17 00:00:00 2001 From: atharvjairath <54663702+atharvjairath@users.noreply.github.com> Date: Tue, 27 Oct 2026 16:57:16 +0530 Subject: [PATCH 1/3] test(http): report missing locale regression coverage --- core/libs/prx/libSceHttp/CMakeLists.txt | 4 ++- core/libs/tests/GuestHttp.cpp | 44 ++++++++++++++++++------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/core/libs/prx/libSceHttp/CMakeLists.txt b/core/libs/prx/libSceHttp/CMakeLists.txt index 701f264762d9..91b7887e66f8 100644 --- a/core/libs/prx/libSceHttp/CMakeLists.txt +++ b/core/libs/prx/libSceHttp/CMakeLists.txt @@ -8,6 +8,8 @@ if(BUILD_TESTING) target_link_libraries(guest_http_tests PRIVATE libSceHttp libc) configure_windows_unwind(guest_http_tests) add_test(NAME guest_http COMMAND guest_http_tests) + add_test(NAME guest_http_uri_locale COMMAND guest_http_tests --uri-locale) + set_tests_properties(guest_http_uri_locale PROPERTIES SKIP_RETURN_CODE 77) add_test_executable(guest_http_response_header_tests ${LIBS_INCLUDE_DIR}/tests/GuestHttpResponseHeader.cpp) target_include_directories(guest_http_response_header_tests PRIVATE ${LIBS_INCLUDE_DIR}) target_link_libraries(guest_http_response_header_tests PRIVATE libSceHttp libc) @@ -19,7 +21,7 @@ if(BUILD_TESTING) configure_windows_unwind(guest_http_options_tests) add_test(NAME guest_http_options COMMAND guest_http_options_tests) if(WIN32) - set_tests_properties(guest_http guest_http_response_header guest_http_options PROPERTIES ENVIRONMENT_MODIFICATION + set_tests_properties(guest_http guest_http_uri_locale guest_http_response_header guest_http_options PROPERTIES ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:$") endif() endif() diff --git a/core/libs/tests/GuestHttp.cpp b/core/libs/tests/GuestHttp.cpp index 661cd4f3cbdf..e1124192b553 100644 --- a/core/libs/tests/GuestHttp.cpp +++ b/core/libs/tests/GuestHttp.cpp @@ -5,9 +5,11 @@ #include "prx/libc/include/general/VabiMacros.hpp" #include #include +#include #include #include #include +#include #include #include #include @@ -425,7 +427,36 @@ static void CheckCaList() { Require(sceHttpsFreeCaList(1, &list) == 0 && list.certs == nullptr && list.certsNum == 0); } -int main() { +static int CheckUriLocales() { + const std::string previousCtype = std::setlocale(LC_CTYPE, nullptr); + bool exercised = false; +#ifdef _WIN32 + const char* locales[] = {".1252"}; +#else + const char* locales[] = {"en_US.ISO8859-1", "en_US.iso88591", "en_US.UTF-8"}; +#endif + for (const char* locale : locales) { + if (!std::setlocale(LC_CTYPE, locale)) continue; + CheckUriEscapeBytes(); + CheckUriParseCharacters(); + const bool classifiesHighByte = std::isalpha(static_cast(0xE9)) != 0; + exercised |= classifiesHighByte; + std::printf("URI locale checks: %s; classifies 0xE9 as alphabetic: %s\n", locale, classifiesHighByte ? "yes" : "no"); + } + Require(std::setlocale(LC_CTYPE, previousCtype.c_str()) != nullptr); +#ifdef _WIN32 + Require(exercised); +#endif + if (!exercised) { + std::fputs("SKIP: URI locale regression requires a Latin-1 locale that classifies 0xE9 as alphabetic.\n", stderr); + return 77; + } + return 0; +} + +int main(int argc, char** argv) { + if (argc == 2 && std::strcmp(argv[1], "--uri-locale") == 0) return CheckUriLocales(); + Require(argc == 1); const std::uint64_t processSize = processParameters.size(); const std::uint32_t processMagic = 0x4942524f; std::uint32_t sdkVersion = 0x1000000; @@ -565,17 +596,6 @@ int main() { Require(std::setlocale(LC_CTYPE, "C") != nullptr); CheckUriEscapeBytes(); CheckUriParseCharacters(); -#ifdef _WIN32 - Require(std::setlocale(LC_CTYPE, ".1252") != nullptr); - CheckUriEscapeBytes(); - CheckUriParseCharacters(); -#else - for (const char* locale : {"en_US.ISO8859-1", "en_US.iso88591", "en_US.UTF-8"}) { - if (!std::setlocale(LC_CTYPE, locale)) continue; - CheckUriEscapeBytes(); - CheckUriParseCharacters(); - } -#endif Require(std::setlocale(LC_CTYPE, previousCtype.c_str()) != nullptr); constexpr const char* unescapeCases[][2] = { From 3eae29619679ce7fa3ef4f49f4f681fe396b02f7 Mon Sep 17 00:00:00 2001 From: atharvjairath <54663702+atharvjairath@users.noreply.github.com> Date: Tue, 27 Oct 2026 18:20:27 +0530 Subject: [PATCH 2/3] test(http): provision private locale for Linux CI --- .github/workflows/build.yml | 19 ++++++++++++++++++- core/libs/prx/libSceHttp/CMakeLists.txt | 6 ++++++ docs/dev/BUILD.md | 4 ++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 547ca0238112..025454b14d8f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -519,7 +519,24 @@ jobs: echo "CCACHE_PREFIX=$GITHUB_WORKSPACE/tools/compile_slot.sh" >> "$GITHUB_ENV" echo "ANYPS5_COMPILE_SLOT_DIR=$slot_dir" >> "$GITHUB_ENV" echo "ANYPS5_COMPILE_SLOTS=$slots" >> "$GITHUB_ENV" - - run: cmake -S . -B build $CONFIGURE -DANYPS5_ENABLE_SPIRV_TOOLS=ON "-DCMAKE_EXE_LINKER_FLAGS=$LINKER_FLAGS" "-DCMAKE_SHARED_LINKER_FLAGS=$LINKER_FLAGS" "-DCMAKE_MODULE_LINKER_FLAGS=$LINKER_FLAGS" + - name: Prepare a private Latin-1 locale for the HTTP regression + shell: bash + run: | + private_root=$(mktemp -d "$RUNNER_TEMP/http-locale.XXXXXX") + i18n=/usr/share/i18n + if [ ! -f "$i18n/locales/en_US" ] || [ ! -f "$i18n/charmaps/ISO-8859-1.gz" ]; then + ( + cd "$private_root" + apt-get download locales + dpkg-deb --extract locales_*.deb data + ) + i18n=$private_root/data/usr/share/i18n + fi + gzip -dc "$i18n/charmaps/ISO-8859-1.gz" > "$private_root/ISO-8859-1" + mkdir -p "$private_root/compiled" + I18NPATH="$i18n" localedef --no-archive -i en_US -f "$private_root/ISO-8859-1" "$private_root/compiled/en_US.ISO8859-1" + echo "HTTP_TEST_LOCALE_DIR=$private_root/compiled" >> "$GITHUB_ENV" + - run: cmake -S . -B build $CONFIGURE -DANYPS5_ENABLE_SPIRV_TOOLS=ON "-DCMAKE_EXE_LINKER_FLAGS=$LINKER_FLAGS" "-DCMAKE_SHARED_LINKER_FLAGS=$LINKER_FLAGS" "-DCMAKE_MODULE_LINKER_FLAGS=$LINKER_FLAGS" "-DANYPS5_HTTP_TEST_LOCALE_DIR=$HTTP_TEST_LOCALE_DIR" - name: Check that every test executable is registered with ctest run: python3 tools/check_test_registration.py build - if: ${{ inputs.select }} diff --git a/core/libs/prx/libSceHttp/CMakeLists.txt b/core/libs/prx/libSceHttp/CMakeLists.txt index 91b7887e66f8..fa26ce569a33 100644 --- a/core/libs/prx/libSceHttp/CMakeLists.txt +++ b/core/libs/prx/libSceHttp/CMakeLists.txt @@ -10,6 +10,12 @@ if(BUILD_TESTING) add_test(NAME guest_http COMMAND guest_http_tests) add_test(NAME guest_http_uri_locale COMMAND guest_http_tests --uri-locale) set_tests_properties(guest_http_uri_locale PROPERTIES SKIP_RETURN_CODE 77) + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(ANYPS5_HTTP_TEST_LOCALE_DIR "" CACHE PATH "Private locale directory for the HTTP URI regression") + if(ANYPS5_HTTP_TEST_LOCALE_DIR) + set_property(TEST guest_http_uri_locale APPEND PROPERTY ENVIRONMENT "LOCPATH=${ANYPS5_HTTP_TEST_LOCALE_DIR}") + endif() + endif() add_test_executable(guest_http_response_header_tests ${LIBS_INCLUDE_DIR}/tests/GuestHttpResponseHeader.cpp) target_include_directories(guest_http_response_header_tests PRIVATE ${LIBS_INCLUDE_DIR}) target_link_libraries(guest_http_response_header_tests PRIVATE libSceHttp libc) diff --git a/docs/dev/BUILD.md b/docs/dev/BUILD.md index 5c9b4ac5a46f..fd542760d661 100644 --- a/docs/dev/BUILD.md +++ b/docs/dev/BUILD.md @@ -139,6 +139,10 @@ SDL and FreeType settings forced by the root `CMakeLists.txt` cannot be overridd With `ANYPS5_USE_SYSTEM_DEPS=ON` those libraries come from the system (on Debian and Ubuntu: `libsdl2-dev`, `libfreetype-dev`, `libvulkan-dev`, `spirv-headers`, `glslang-dev`, `glslang-tools` and `spirv-tools`). A missing package, Vulkan-Headers older than 1.4.310 (the agc driver uses `VK_KHR_maintenance8`), or an SDL2 without the HIDAPI joystick driver (sdl2-compat over SDL3, or a build with HIDAPI disabled, which breaks the pad and disk-audio tests), fails the configure with an error and never falls back to the submodule. The forced SDL and FreeType settings from the root `CMakeLists.txt` do not apply with the flag ON: the system SDL2 comes with whatever its distribution enabled. The prx libraries are shared objects, so SDL2 is linked from the system as a shared library; the default build keeps its own static SDL2. `ffmpeg-core`, `libjpeg-turbo`, `stb`, `VulkanMemoryAllocator`, `LibAtrac9`, `ogg` and `vorbis` always stay bundled and still need `git submodule update --init`. +## HTTP locale tests + +The Linux HTTP URI locale regression needs an ISO-8859-1 locale. CI builds a private `en_US.ISO8859-1` with `localedef`, using installed locale sources or an extracted `locales` package without installing it or changing system locales. `-DANYPS5_HTTP_TEST_LOCALE_DIR=` gives only `guest_http_uri_locale` that directory through `LOCPATH`. Without an effective Latin-1 locale the test explicitly skips; the CI skip audit rejects that loss of coverage. Windows requires `.1252`. + ## ThreadSanitizer A ThreadSanitizer build runs its tests with `TSAN_OPTIONS=suppressions=$PWD/tools/tsan-suppressions.txt`, which silences reports from Mesa's lavapipe, the LLVM it compiles shaders with, and PulseAudio: those system libraries are not instrumented, so ThreadSanitizer cannot see their locking. Guest memory written by the emulated GPU while a guest thread polls it, such as labels and fences, is shared without C++ atomics on purpose, as on the console, so ThreadSanitizer also reports those accesses. From 384d3436deddce0c9995eeeebd1c47a292653af6 Mon Sep 17 00:00:00 2001 From: atharvjairath <54663702+atharvjairath@users.noreply.github.com> Date: Wed, 28 Oct 2026 23:42:14 +0530 Subject: [PATCH 3/3] fix(http): provision the URI test locale during configure --- .github/workflows/build.yml | 19 +------------------ core/libs/prx/libSceHttp/CMakeLists.txt | 22 ++++++++++++++++++++-- docs/dev/BUILD.md | 2 +- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 025454b14d8f..547ca0238112 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -519,24 +519,7 @@ jobs: echo "CCACHE_PREFIX=$GITHUB_WORKSPACE/tools/compile_slot.sh" >> "$GITHUB_ENV" echo "ANYPS5_COMPILE_SLOT_DIR=$slot_dir" >> "$GITHUB_ENV" echo "ANYPS5_COMPILE_SLOTS=$slots" >> "$GITHUB_ENV" - - name: Prepare a private Latin-1 locale for the HTTP regression - shell: bash - run: | - private_root=$(mktemp -d "$RUNNER_TEMP/http-locale.XXXXXX") - i18n=/usr/share/i18n - if [ ! -f "$i18n/locales/en_US" ] || [ ! -f "$i18n/charmaps/ISO-8859-1.gz" ]; then - ( - cd "$private_root" - apt-get download locales - dpkg-deb --extract locales_*.deb data - ) - i18n=$private_root/data/usr/share/i18n - fi - gzip -dc "$i18n/charmaps/ISO-8859-1.gz" > "$private_root/ISO-8859-1" - mkdir -p "$private_root/compiled" - I18NPATH="$i18n" localedef --no-archive -i en_US -f "$private_root/ISO-8859-1" "$private_root/compiled/en_US.ISO8859-1" - echo "HTTP_TEST_LOCALE_DIR=$private_root/compiled" >> "$GITHUB_ENV" - - run: cmake -S . -B build $CONFIGURE -DANYPS5_ENABLE_SPIRV_TOOLS=ON "-DCMAKE_EXE_LINKER_FLAGS=$LINKER_FLAGS" "-DCMAKE_SHARED_LINKER_FLAGS=$LINKER_FLAGS" "-DCMAKE_MODULE_LINKER_FLAGS=$LINKER_FLAGS" "-DANYPS5_HTTP_TEST_LOCALE_DIR=$HTTP_TEST_LOCALE_DIR" + - run: cmake -S . -B build $CONFIGURE -DANYPS5_ENABLE_SPIRV_TOOLS=ON "-DCMAKE_EXE_LINKER_FLAGS=$LINKER_FLAGS" "-DCMAKE_SHARED_LINKER_FLAGS=$LINKER_FLAGS" "-DCMAKE_MODULE_LINKER_FLAGS=$LINKER_FLAGS" - name: Check that every test executable is registered with ctest run: python3 tools/check_test_registration.py build - if: ${{ inputs.select }} diff --git a/core/libs/prx/libSceHttp/CMakeLists.txt b/core/libs/prx/libSceHttp/CMakeLists.txt index fa26ce569a33..ab630f375c88 100644 --- a/core/libs/prx/libSceHttp/CMakeLists.txt +++ b/core/libs/prx/libSceHttp/CMakeLists.txt @@ -12,8 +12,26 @@ if(BUILD_TESTING) set_tests_properties(guest_http_uri_locale PROPERTIES SKIP_RETURN_CODE 77) if(CMAKE_SYSTEM_NAME STREQUAL "Linux") set(ANYPS5_HTTP_TEST_LOCALE_DIR "" CACHE PATH "Private locale directory for the HTTP URI regression") - if(ANYPS5_HTTP_TEST_LOCALE_DIR) - set_property(TEST guest_http_uri_locale APPEND PROPERTY ENVIRONMENT "LOCPATH=${ANYPS5_HTTP_TEST_LOCALE_DIR}") + set(http_test_locale_dir "${ANYPS5_HTTP_TEST_LOCALE_DIR}") + if(NOT http_test_locale_dir AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") + set(private_locale_dir "${CMAKE_CURRENT_BINARY_DIR}/locales") + file(MAKE_DIRECTORY "${private_locale_dir}") + execute_process( + COMMAND localedef --no-archive -i en_US -f ISO-8859-1 "${private_locale_dir}/en_US.ISO8859-1" + RESULT_VARIABLE locale_result + OUTPUT_VARIABLE locale_output + ERROR_VARIABLE locale_error + TIMEOUT 30 + ) + if(locale_result STREQUAL "0") + set(http_test_locale_dir "${private_locale_dir}") + message(STATUS "HTTP URI locale: ${http_test_locale_dir}") + else() + message(STATUS "HTTP URI locale unavailable (${locale_result}): ${locale_output}${locale_error}") + endif() + endif() + if(http_test_locale_dir) + set_property(TEST guest_http_uri_locale APPEND PROPERTY ENVIRONMENT "LOCPATH=${http_test_locale_dir}") endif() endif() add_test_executable(guest_http_response_header_tests ${LIBS_INCLUDE_DIR}/tests/GuestHttpResponseHeader.cpp) diff --git a/docs/dev/BUILD.md b/docs/dev/BUILD.md index fd542760d661..43e19da1fdb3 100644 --- a/docs/dev/BUILD.md +++ b/docs/dev/BUILD.md @@ -141,7 +141,7 @@ With `ANYPS5_USE_SYSTEM_DEPS=ON` those libraries come from the system (on Debian ## HTTP locale tests -The Linux HTTP URI locale regression needs an ISO-8859-1 locale. CI builds a private `en_US.ISO8859-1` with `localedef`, using installed locale sources or an extracted `locales` package without installing it or changing system locales. `-DANYPS5_HTTP_TEST_LOCALE_DIR=` gives only `guest_http_uri_locale` that directory through `LOCPATH`. Without an effective Latin-1 locale the test explicitly skips; the CI skip audit rejects that loss of coverage. Windows requires `.1252`. +The Linux HTTP URI locale regression needs an ISO-8859-1 locale. With tests enabled, CMake uses host `localedef` and installed locale sources to generate a private `en_US.ISO8859-1` under the HTTP build directory. This runs from the checked-out PR tree, including when CI dispatches the workflow from `main`, and changes no system locales. `-DANYPS5_HTTP_TEST_LOCALE_DIR=` overrides generation. Only `guest_http_uri_locale` receives the private directory through `LOCPATH`. If `localedef` or its source data is unavailable, configuration reports it and leaves the test to probe installed locales. Without an effective Latin-1 locale the test explicitly skips; the CI skip audit rejects that loss of coverage. Windows requires `.1252`. ## ThreadSanitizer