From 3165bb622b927938a8e561c073eb1560c88282eb Mon Sep 17 00:00:00 2001 From: ADEMOLA200 Date: Wed, 3 Dec 2025 20:01:06 +0100 Subject: [PATCH] edge case --- src/core/libraries/network/http.cpp | 37 ++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/core/libraries/network/http.cpp b/src/core/libraries/network/http.cpp index 4feb267e3..0fb81c639 100644 --- a/src/core/libraries/network/http.cpp +++ b/src/core/libraries/network/http.cpp @@ -1,8 +1,6 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include -#include #include "common/logging/log.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" @@ -723,7 +721,8 @@ int PS4_SYSV_ABI sceHttpUriEscape(char* out, u64* require, u64 prepare, const ch } auto IsUnreserved = [](unsigned char c) -> bool { - return std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~'; + return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || + c == '-' || c == '_' || c == '.' || c == '~'; }; u64 needed = 0; @@ -743,7 +742,6 @@ int PS4_SYSV_ABI sceHttpUriEscape(char* out, u64* require, u64 prepare, const ch *require = needed; } - // If only calculating size, return success if (!out) { return ORBIS_OK; } @@ -1139,11 +1137,31 @@ int PS4_SYSV_ABI sceHttpUriUnescape(char* out, u64* require, u64 prepare, const return ORBIS_HTTP_ERROR_INVALID_VALUE; } + // Locale-independent hex digit check + auto IsHex = [](char c) -> bool { + return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); + }; + + // Convert hex char to int value + auto HexToInt = [](char c) -> int { + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 0; + }; + + // Check for valid percent-encoded sequence (%XX) + auto IsValidPercentSequence = [&](const char* s) -> bool { + return s[0] == '%' && s[1] != '\0' && s[2] != '\0' && IsHex(s[1]) && IsHex(s[2]); + }; + u64 needed = 0; const char* src = in; while (*src) { - if (*src == '%' && std::isxdigit(static_cast(src[1])) && - std::isxdigit(static_cast(src[2]))) { + if (IsValidPercentSequence(src)) { src += 3; } else { src++; @@ -1156,7 +1174,6 @@ int PS4_SYSV_ABI sceHttpUriUnescape(char* out, u64* require, u64 prepare, const *require = needed; } - // If only calculating size, return success if (!out) { return ORBIS_OK; } @@ -1169,10 +1186,8 @@ int PS4_SYSV_ABI sceHttpUriUnescape(char* out, u64* require, u64 prepare, const src = in; char* dst = out; while (*src) { - if (*src == '%' && std::isxdigit(static_cast(src[1])) && - std::isxdigit(static_cast(src[2]))) { - char hex[3] = {src[1], src[2], '\0'}; - *dst++ = static_cast(std::strtol(hex, nullptr, 16)); + if (IsValidPercentSequence(src)) { + *dst++ = static_cast((HexToInt(src[1]) << 4) | HexToInt(src[2])); src += 3; } else { *dst++ = *src++;