From e926644cd9f12c751b31a1a0acde7e4327722627 Mon Sep 17 00:00:00 2001 From: am11 <3840695+am11@users.noreply.github.com> Date: Wed, 4 Nov 2026 19:27:30 +0200 Subject: [PATCH 01/13] Add native tests for the minipal UTF-8 conversions Port everything the PAL MultiByteToWideChar and WideCharToMultiByte tests cover to direct minipal_* calls, so they can replace those tests: valid and ill-formed input with and without the terminator, embedded in ASCII runs, embedded NULs, size queries, exactly sized and too small destinations, errno, MINIPAL_MB_NO_REPLACE_INVALID_CHARS, and MINIPAL_TREAT_AS_LITTLE_ENDIAN parity on big- and little-endian platforms. Add long runs around the UTF-16 lane count flush, and random input checked against a simple reference model. --- .../eventpipe/native/minipal/CMakeLists.txt | 18 + .../native/minipal/NativeMinipalTests.cs | 18 + .../native/minipal/NativeMinipalTests.csproj | 7 + .../minipal/native-minipal-tests-driver.c | 16 + .../eventpipe/native/minipal/utf8-tests.c | 1049 +++++++++++++++++ 5 files changed, 1108 insertions(+) create mode 100644 src/tests/tracing/eventpipe/native/minipal/CMakeLists.txt create mode 100644 src/tests/tracing/eventpipe/native/minipal/NativeMinipalTests.cs create mode 100644 src/tests/tracing/eventpipe/native/minipal/NativeMinipalTests.csproj create mode 100644 src/tests/tracing/eventpipe/native/minipal/native-minipal-tests-driver.c create mode 100644 src/tests/tracing/eventpipe/native/minipal/utf8-tests.c diff --git a/src/tests/tracing/eventpipe/native/minipal/CMakeLists.txt b/src/tests/tracing/eventpipe/native/minipal/CMakeLists.txt new file mode 100644 index 00000000000000..84adfbc33756e3 --- /dev/null +++ b/src/tests/tracing/eventpipe/native/minipal/CMakeLists.txt @@ -0,0 +1,18 @@ +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) + +if(CLR_CMAKE_TARGET_ANDROID OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_ARCH_WASM) + return() +endif() + +include_directories(${CLR_SRC_NATIVE_DIR}) + +add_executable(NativeMinipalTestsDriver + ../common/driver.c + ../common/test.c + native-minipal-tests-driver.c + utf8-tests.c) + +target_include_directories(NativeMinipalTestsDriver PRIVATE ../common) +target_link_libraries(NativeMinipalTestsDriver PRIVATE minipal) +install(TARGETS NativeMinipalTestsDriver DESTINATION bin) diff --git a/src/tests/tracing/eventpipe/native/minipal/NativeMinipalTests.cs b/src/tests/tracing/eventpipe/native/minipal/NativeMinipalTests.cs new file mode 100644 index 00000000000000..23a678bad86c18 --- /dev/null +++ b/src/tests/tracing/eventpipe/native/minipal/NativeMinipalTests.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Xunit; + +public class NativeMinipalTests +{ + [Theory] + [InlineData("utf8")] + public static void RunSuite(string group) + { + (int exitCode, string output, string error) = NativeTestProcess.Run("NativeMinipalTestsDriver", group); + Console.Write(output); + Console.Error.Write(error); + Assert.Equal(0, exitCode); + } +} diff --git a/src/tests/tracing/eventpipe/native/minipal/NativeMinipalTests.csproj b/src/tests/tracing/eventpipe/native/minipal/NativeMinipalTests.csproj new file mode 100644 index 00000000000000..03acd75ea79f36 --- /dev/null +++ b/src/tests/tracing/eventpipe/native/minipal/NativeMinipalTests.csproj @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/tests/tracing/eventpipe/native/minipal/native-minipal-tests-driver.c b/src/tests/tracing/eventpipe/native/minipal/native-minipal-tests-driver.c new file mode 100644 index 00000000000000..59899dba334103 --- /dev/null +++ b/src/tests/tracing/eventpipe/native/minipal/native-minipal-tests-driver.c @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "test.h" + +DEFINE_TEST_GROUP_INIT_H(minipal_utf8_tests_init); + +static const Group test_groups[] = { + {"utf8", minipal_utf8_tests_init}, + {NULL, NULL} +}; + +int DN_CALLBACK_CALLTYPE main(int argc, char **argv) +{ + return run_tests_main(test_groups, argc, argv); +} diff --git a/src/tests/tracing/eventpipe/native/minipal/utf8-tests.c b/src/tests/tracing/eventpipe/native/minipal/utf8-tests.c new file mode 100644 index 00000000000000..49b2aad3ade1d2 --- /dev/null +++ b/src/tests/tracing/eventpipe/native/minipal/utf8-tests.c @@ -0,0 +1,1049 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "test.h" + +#include +#include +#include + +#define W(str) ((const CHAR16_T*)u##str) + +#define CHECK(call) do { RESULT check_result = (call); if (check_result != OK) return check_result; } while (0) + +// A value the conversions never set, to see that they clear errno when they succeed +#define ERRNO_SENTINEL 12345 + +#define REPLACEMENT_CHAR 0xFFFD + +static const CHAR16_T Utf16Canary = 0xBEEF; +static const char Utf8Canary = '\xA5'; + +typedef struct +{ + const char* utf8; + const CHAR16_T* utf16; +} StringPair; + +typedef struct +{ + const char* utf8; + size_t utf8Length; + const CHAR16_T* utf16; + size_t utf16Length; +} CountedStringPair; + +// Strings that convert both ways +static const StringPair valid_strings[] = +{ + // Empty string + { "", W("") }, + // 1, 2 and 3 byte encoded 1 character long strings + { "A", W("A") }, + { "\xC2\x80", W("\x0080") }, + { "\xE0\xA0\x80", W("\x0800") }, + // 1 byte encoded characters only + { "ABCDEFGHIJKLMNOPQRSTUVWXYZ", W("ABCDEFGHIJKLMNOPQRSTUVWXYZ") }, + // 2 byte encoded characters only + { "\xC2\x80\xC3\xBF\xC7\x81\xDF\xBF", W("\x0080\x00FF\x01C1\x07FF") }, + // 3 byte encoded characters only + { "\xE0\xA0\x80\xE1\xB6\x88\xE1\x80\x80\xEF\xBF\xBF", W("\x0800\x1D88\x1000\xFFFF") }, + // 1 and 2 byte encoded characters interleaved 1:1, starting and ending with either + { "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45", W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045") }, + { "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF", W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF") }, + { "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45", W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045") }, + { "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF", W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF") }, + // 1 and 2 byte encoded characters interleaved 2:2, starting and ending with either + { "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46", W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046") }, + { "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF", W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF") }, + { "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46", W("\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046") }, + { "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF", W("\x0080\x00FF\x0043\x0044\x01C1\x07FF") }, + // 4 byte encoded characters, which are surrogate pairs in UTF-16 + { "\xF0\x90\x80\x80\xF0\x90\x89\x80\xF3\x80\x8E\xB0\xF4\x8F\xBF\xBF", W("\xD800\xDC00\xD800\xDE40\xDAC0\xDFB0\xDBFF\xDFFF") }, +}; + +// Ill-formed UTF-8 and the UTF-16 it converts to +static const StringPair invalid_utf8_strings[] = +{ + // Incomplete 2, 3 and 4 byte encoded characters standalone + { "\xC2", W("\xFFFD") }, + { "\xE0\xA0", W("\xFFFD") }, + { "\xE0", W("\xFFFD") }, + { "\xF0\x90\x80", W("\xFFFD") }, + { "\xF0\x90", W("\xFFFD") }, + { "\xF0", W("\xFFFD") }, + // Continuation byte with no lead byte standalone + { "\x80", W("\xFFFD") }, + // The same between, before and after 1 byte encoded characters + { "\x41\xC2\x42", W("\x0041\xFFFD\x0042") }, + { "\x41\xE0\xA0\x42", W("\x0041\xFFFD\x0042") }, + { "\x41\xE0\x42", W("\x0041\xFFFD\x0042") }, + { "\x41\x80\x42", W("\x0041\xFFFD\x0042") }, + { "\xC2\x42", W("\xFFFD\x0042") }, + { "\xE0\xA0\x42", W("\xFFFD\x0042") }, + { "\xE0\x42", W("\xFFFD\x0042") }, + { "\x80\x42", W("\xFFFD\x0042") }, + { "\x41\xC2", W("\x0041\xFFFD") }, + { "\x41\xE0\xA0", W("\x0041\xFFFD") }, + { "\x41\xE0", W("\x0041\xFFFD") }, + { "\x41\x80", W("\x0041\xFFFD") }, + // ... and between 2 byte encoded characters + { "\xC2\x80\xC2\xC3\xBF", W("\x0080\xFFFD\x00FF") }, + { "\xC2\x80\xE0\xA0\xC3\xBF", W("\x0080\xFFFD\x00FF") }, + { "\xC2\x80\xE0\xC3\xBF", W("\x0080\xFFFD\x00FF") }, + { "\xC2\x80\x80\xC3\xBF", W("\x0080\xFFFD\x00FF") }, + // Non-shortest form encodings + { "\xC0\x80", W("\xFFFD\xFFFD") }, + { "\xE0\x80\x80", W("\xFFFD\xFFFD") }, + { "\xF0\x80\x80\x80", W("\xFFFD\xFFFD\xFFFD") }, + // ... of the largest character of each shorter form + { "\xC1\xBF", W("\xFFFD\xFFFD") }, + { "\xE0\x9F\xBF", W("\xFFFD\xFFFD") }, + { "\xF0\x8F\xBF\xBF", W("\xFFFD\xFFFD\xFFFD") }, + // Encoded high and low surrogates, a pair of them (CESU-8), and one between 1 byte encoded characters + { "\xED\xA0\x80", W("\xFFFD\xFFFD") }, + { "\xED\xBF\xBF", W("\xFFFD\xFFFD") }, + { "\xED\xA0\x80\xED\xB0\x80", W("\xFFFD\xFFFD\xFFFD\xFFFD") }, + { "\x41\xED\xBF\xBF\x42", W("\x0041\xFFFD\xFFFD\x0042") }, + // 4 byte encoded character above U+10FFFF, and lead bytes that can only encode such characters + { "\xF4\x90\x80\x80", W("\xFFFD\xFFFD\xFFFD") }, + { "\xF5\x80\x80\x80", W("\xFFFD\xFFFD\xFFFD\xFFFD") }, + { "\xF7\xBF\xBF\xBF", W("\xFFFD\xFFFD\xFFFD\xFFFD") }, + // 5 and 6 byte encodings + { "\xF8\x88\x80\x80\x80", W("\xFFFD\xFFFD\xFFFD\xFFFD\xFFFD") }, + { "\xFC\x84\x80\x80\x80\x80", W("\xFFFD\xFFFD\xFFFD\xFFFD\xFFFD\xFFFD") }, + // Bytes that never appear in UTF-8 + { "\xFE", W("\xFFFD") }, + { "\xFF", W("\xFFFD") }, + { "\x41\xFE\x42\xFF\x43", W("\x0041\xFFFD\x0042\xFFFD\x0043") }, +}; + +// Ill-formed UTF-16 and the UTF-8 it converts to +static const StringPair invalid_utf16_strings[] = +{ + // Lone high and low surrogates standalone, after a character and between two characters + { "\xEF\xBF\xBD", W("\xD800") }, + { "\xEF\xBF\xBD", W("\xDC00") }, + { "\x41\xEF\xBF\xBD", W("\x0041\xD800") }, + { "\x41\xEF\xBF\xBD", W("\x0041\xDC00") }, + { "\x41\xEF\xBF\xBD\x42", W("\x0041\xD800\x0042") }, + { "\x41\xEF\xBF\xBD\x42", W("\x0041\xDC00\x0042") }, + // Low surrogate followed by high surrogate, standalone and between two characters + { "\xEF\xBF\xBD\xEF\xBF\xBD", W("\xDC00\xD800") }, + { "\x41\xEF\xBF\xBD\xEF\xBF\xBD\x42", W("\x0041\xDC00\xD800\x0042") }, + // High surrogate followed by a surrogate pair, and a surrogate pair followed by a low surrogate + { "\xEF\xBF\xBD\xF0\x90\x80\x80", W("\xD800\xD800\xDC00") }, + { "\xF0\x90\x80\x80\xEF\xBF\xBD", W("\xD800\xDC00\xDC00") }, +}; + +// Explicit lengths that include NULs, which convert like any other character +static const CountedStringPair utf8_strings_with_nuls[] = +{ + { "\0", 1, W("\0"), 1 }, + { "\0\0", 2, W("\0\0"), 2 }, + { "a\0b", 3, W("a\0b"), 3 }, + // Incomplete 2 byte encoded character before a NUL, and a continuation byte after it + { "\xC2\0\x80", 3, W("\xFFFD\0\xFFFD"), 3 }, + // Incomplete 2 byte encoded character at the end, after a NUL + { "a\0\xC2", 3, W("a\0\xFFFD"), 3 }, + // 4 byte encoded character interrupted by a NUL, and one after a NUL + { "\xF0\x90\0\x80\x80", 5, W("\xFFFD\0\xFFFD\xFFFD"), 4 }, + { "A\0\xF0\x90\x80\x80", 6, W("A\0\xD800\xDC00"), 4 }, +}; + +static const CountedStringPair utf16_strings_with_nuls[] = +{ + { "\0", 1, W("\0"), 1 }, + { "a\0b", 3, W("a\0b"), 3 }, + // Surrogate pair interrupted by a NUL, and one after a NUL + { "\xEF\xBF\xBD\0\xEF\xBF\xBD", 7, W("\xD800\0\xDC00"), 3 }, + { "\0\xF0\x9F\x98\x80", 5, W("\0\xD83D\xDE00"), 3 }, + // High surrogate before a NUL at the end + { "\xEF\xBF\xBD\0", 4, W("\xD800\0"), 2 }, +}; + +static bool is_big_endian(void) +{ + const uint16_t one = 1; + return *(const uint8_t*)&one == 0; +} + +static CHAR16_T swap_bytes(CHAR16_T c) +{ + return (CHAR16_T)((c << 8) | (c >> 8)); +} + +static size_t utf16_length(const CHAR16_T* s) +{ + size_t length = 0; + while (s[length] != 0) + length++; + return length; +} + +static bool has_replacement_char(const CHAR16_T* s, size_t length) +{ + for (size_t i = 0; i < length; i++) + { + if (s[i] == REPLACEMENT_CHAR) + return true; + } + return false; +} + +static void fill_utf16(CHAR16_T* buffer, size_t length) +{ + for (size_t i = 0; i < length; i++) + buffer[i] = Utf16Canary; +} + +static bool is_high_surrogate(uint32_t c) +{ + return c >= 0xD800 && c <= 0xDBFF; +} + +static bool is_low_surrogate(uint32_t c) +{ + return c >= 0xDC00 && c <= 0xDFFF; +} + +// A character at a time model of the conversions, which the optimized paths must agree with + +static size_t reference_encode_utf8(uint32_t codePoint, unsigned char* p) +{ + if (codePoint < 0x80) + { + p[0] = (unsigned char)codePoint; + return 1; + } + if (codePoint < 0x800) + { + p[0] = (unsigned char)(0xC0 | (codePoint >> 6)); + p[1] = (unsigned char)(0x80 | (codePoint & 0x3F)); + return 2; + } + if (codePoint < 0x10000) + { + p[0] = (unsigned char)(0xE0 | (codePoint >> 12)); + p[1] = (unsigned char)(0x80 | ((codePoint >> 6) & 0x3F)); + p[2] = (unsigned char)(0x80 | (codePoint & 0x3F)); + return 3; + } + p[0] = (unsigned char)(0xF0 | (codePoint >> 18)); + p[1] = (unsigned char)(0x80 | ((codePoint >> 12) & 0x3F)); + p[2] = (unsigned char)(0x80 | ((codePoint >> 6) & 0x3F)); + p[3] = (unsigned char)(0x80 | (codePoint & 0x3F)); + return 4; +} + +// Decodes one sequence and returns its length in bytes. An ill-formed sequence decodes to -1, and is an invalid lead +// byte, a lead byte with an out of range second byte, or a lead byte with the continuation bytes that follow it before +// the input ends or a byte that isn't a continuation byte. The ranges are the well-formed sequences of the Unicode +// standard (Table 3-7). +static size_t reference_decode_utf8(const unsigned char* p, size_t available, int32_t* codePoint) +{ + static const struct + { + unsigned char firstLead; + unsigned char lastLead; + unsigned char length; + unsigned char secondLow; + unsigned char secondHigh; + } sequences[] = + { + { 0x00, 0x7F, 1, 0, 0 }, + { 0xC2, 0xDF, 2, 0x80, 0xBF }, + { 0xE0, 0xE0, 3, 0xA0, 0xBF }, + { 0xE1, 0xEC, 3, 0x80, 0xBF }, + { 0xED, 0xED, 3, 0x80, 0x9F }, + { 0xEE, 0xEF, 3, 0x80, 0xBF }, + { 0xF0, 0xF0, 4, 0x90, 0xBF }, + { 0xF1, 0xF3, 4, 0x80, 0xBF }, + { 0xF4, 0xF4, 4, 0x80, 0x8F }, + }; + + for (size_t i = 0; i < ARRAY_SIZE(sequences); i++) + { + if (p[0] < sequences[i].firstLead || p[0] > sequences[i].lastLead) + continue; + + int32_t value = sequences[i].length == 1 ? p[0] : p[0] & (0x7F >> sequences[i].length); + for (size_t j = 1; j < sequences[i].length; j++) + { + if (j >= available || (p[j] & 0xC0) != 0x80) + { + *codePoint = -1; + return j; + } + + if (j == 1 && (p[1] < sequences[i].secondLow || p[1] > sequences[i].secondHigh)) + { + *codePoint = -1; + return 2; + } + + value = (value << 6) | (p[j] & 0x3F); + } + + *codePoint = value; + return sequences[i].length; + } + + *codePoint = -1; + return 1; +} + +static size_t reference_utf8_to_utf16(const char* source, size_t sourceLength, CHAR16_T* destination, bool* invalid) +{ + const unsigned char* p = (const unsigned char*)source; + size_t written = 0; + + *invalid = false; + for (size_t i = 0; i < sourceLength;) + { + int32_t codePoint; + i += reference_decode_utf8(p + i, sourceLength - i, &codePoint); + if (codePoint < 0) + { + *invalid = true; + codePoint = REPLACEMENT_CHAR; + } + + if (codePoint >= 0x10000) + { + destination[written++] = (CHAR16_T)(0xD800 + ((codePoint - 0x10000) >> 10)); + destination[written++] = (CHAR16_T)(0xDC00 + (codePoint & 0x3FF)); + } + else + { + destination[written++] = (CHAR16_T)codePoint; + } + } + + return written; +} + +// A lone surrogate converts to the replacement character +static size_t reference_utf16_to_utf8(const CHAR16_T* source, size_t sourceLength, char* destination) +{ + unsigned char* p = (unsigned char*)destination; + size_t written = 0; + + for (size_t i = 0; i < sourceLength; i++) + { + uint32_t codePoint = source[i]; + if (is_high_surrogate(codePoint) && i + 1 < sourceLength && is_low_surrogate(source[i + 1])) + { + codePoint = 0x10000 + ((codePoint - 0xD800) << 10) + (source[i + 1] - 0xDC00u); + i++; + } + else if (is_high_surrogate(codePoint) || is_low_surrogate(codePoint)) + { + codePoint = REPLACEMENT_CHAR; + } + + written += reference_encode_utf8(codePoint, p + written); + } + + return written; +} + +// Checks the size query, an exactly sized destination, destinations that are too small, MINIPAL_MB_NO_REPLACE_INVALID_CHARS +// and MINIPAL_TREAT_AS_LITTLE_ENDIAN for one input. invalid tells whether the input has ill-formed sequences. The buffers +// have room for capacity code units, more than expectedLength. +static RESULT check_utf8_to_utf16_in(const char* name, size_t index, size_t variant, + const char* source, size_t sourceLength, const CHAR16_T* expected, size_t expectedLength, bool invalid, + CHAR16_T* native, CHAR16_T* little, size_t capacity) +{ + size_t count; + int error; + + errno = ERRNO_SENTINEL; + count = minipal_get_length_utf8_to_utf16(source, sourceLength, 0); + error = errno; + if (count != expectedLength || error != 0) + { + return FAILED("%s %zu.%zu: minipal_get_length_utf8_to_utf16 returned %zu with errno %d, expected %zu", + name, index, variant, count, error, expectedLength); + } + + // An exactly sized destination gets the whole string and nothing past it + fill_utf16(native, capacity); + errno = ERRNO_SENTINEL; + count = minipal_convert_utf8_to_utf16(source, sourceLength, native, expectedLength, 0); + error = errno; + if (count != expectedLength || error != 0 || memcmp(native, expected, expectedLength * sizeof(CHAR16_T)) != 0 || + native[expectedLength] != Utf16Canary) + { + return FAILED("%s %zu.%zu: minipal_convert_utf8_to_utf16 returned %zu with errno %d, expected %zu, or produced an unexpected string", + name, index, variant, count, error, expectedLength); + } + + // Destinations that are too small fail without writing past their end + if (expectedLength != 0) + { + const size_t sizes[] = { expectedLength - 1, 0 }; + for (size_t s = 0; s < ARRAY_SIZE(sizes); s++) + { + fill_utf16(native, capacity); + count = minipal_convert_utf8_to_utf16(source, sourceLength, native, sizes[s], 0); + error = errno; + if (count != 0 || error != MINIPAL_ERROR_INSUFFICIENT_BUFFER || native[sizes[s]] != Utf16Canary) + { + return FAILED("%s %zu.%zu: minipal_convert_utf8_to_utf16 into %zu elements returned %zu with errno %d, expected 0 with MINIPAL_ERROR_INSUFFICIENT_BUFFER and nothing written past them", + name, index, variant, sizes[s], count, error); + } + } + } + + // MINIPAL_MB_NO_REPLACE_INVALID_CHARS fails on any ill-formed sequence, including one at the end of the input + const size_t strictLength = invalid ? 0 : expectedLength; + const int strictError = invalid ? (int)MINIPAL_ERROR_NO_UNICODE_TRANSLATION : 0; + errno = ERRNO_SENTINEL; + count = minipal_get_length_utf8_to_utf16(source, sourceLength, MINIPAL_MB_NO_REPLACE_INVALID_CHARS); + error = errno; + if (count != strictLength || error != strictError) + { + return FAILED("%s %zu.%zu: minipal_get_length_utf8_to_utf16 with MINIPAL_MB_NO_REPLACE_INVALID_CHARS returned %zu with errno %d, expected %zu with errno %d", + name, index, variant, count, error, strictLength, strictError); + } + + fill_utf16(native, capacity); + errno = ERRNO_SENTINEL; + count = minipal_convert_utf8_to_utf16(source, sourceLength, native, capacity, MINIPAL_MB_NO_REPLACE_INVALID_CHARS); + error = errno; + if (count != strictLength || error != strictError || memcmp(native, expected, strictLength * sizeof(CHAR16_T)) != 0) + { + return FAILED("%s %zu.%zu: minipal_convert_utf8_to_utf16 with MINIPAL_MB_NO_REPLACE_INVALID_CHARS returned %zu with errno %d, expected %zu with errno %d", + name, index, variant, count, error, strictLength, strictError); + } + + // MINIPAL_TREAT_AS_LITTLE_ENDIAN gives the native result with each code unit byte-swapped on big-endian platforms, + // and the native result elsewhere, for any destination size + const bool bigEndian = is_big_endian(); + const unsigned int flagSets[] = { 0, MINIPAL_MB_NO_REPLACE_INVALID_CHARS }; + const size_t sizes[] = { expectedLength, expectedLength != 0 ? expectedLength - 1 : 0, capacity }; + for (size_t f = 0; f < ARRAY_SIZE(flagSets); f++) + { + const unsigned int flags = flagSets[f]; + + errno = ERRNO_SENTINEL; + size_t nativeCount = minipal_get_length_utf8_to_utf16(source, sourceLength, flags); + int nativeError = errno; + errno = ERRNO_SENTINEL; + size_t littleCount = minipal_get_length_utf8_to_utf16(source, sourceLength, flags | MINIPAL_TREAT_AS_LITTLE_ENDIAN); + int littleError = errno; + if (littleCount != nativeCount || littleError != nativeError) + { + return FAILED("%s %zu.%zu: minipal_get_length_utf8_to_utf16 with flags 0x%x returned %zu with errno %d for little-endian, %zu with errno %d otherwise", + name, index, variant, flags, littleCount, littleError, nativeCount, nativeError); + } + + for (size_t s = 0; s < ARRAY_SIZE(sizes); s++) + { + fill_utf16(native, capacity); + fill_utf16(little, capacity); + errno = ERRNO_SENTINEL; + nativeCount = minipal_convert_utf8_to_utf16(source, sourceLength, native, sizes[s], flags); + nativeError = errno; + errno = ERRNO_SENTINEL; + littleCount = minipal_convert_utf8_to_utf16(source, sourceLength, little, sizes[s], flags | MINIPAL_TREAT_AS_LITTLE_ENDIAN); + littleError = errno; + if (littleCount != nativeCount || littleError != nativeError) + { + return FAILED("%s %zu.%zu: minipal_convert_utf8_to_utf16 with flags 0x%x into %zu elements returned %zu with errno %d for little-endian, %zu with errno %d otherwise", + name, index, variant, flags, sizes[s], littleCount, littleError, nativeCount, nativeError); + } + + for (size_t i = 0; i < nativeCount; i++) + { + const CHAR16_T expectedUnit = bigEndian ? swap_bytes(native[i]) : native[i]; + if (little[i] != expectedUnit) + { + return FAILED("%s %zu.%zu: minipal_convert_utf8_to_utf16 with flags 0x%x into %zu elements wrote 0x%04x at %zu for little-endian, expected 0x%04x", + name, index, variant, flags, sizes[s], (unsigned)little[i], i, (unsigned)expectedUnit); + } + } + } + } + + return OK; +} + +static RESULT check_utf8_to_utf16(const char* name, size_t index, size_t variant, + const char* source, size_t sourceLength, const CHAR16_T* expected, size_t expectedLength, bool invalid) +{ + const size_t capacity = expectedLength + 16; + CHAR16_T* native = (CHAR16_T*)malloc(capacity * sizeof(CHAR16_T)); + CHAR16_T* little = (CHAR16_T*)malloc(capacity * sizeof(CHAR16_T)); + RESULT result = native != NULL && little != NULL + ? check_utf8_to_utf16_in(name, index, variant, source, sourceLength, expected, expectedLength, invalid, native, little, capacity) + : FAILED("%s %zu.%zu: out of memory", name, index, variant); + free(native); + free(little); + return result; +} + +// Converts a NUL-terminated string without and with its terminator +static RESULT check_utf8_string(const char* name, size_t index, size_t variant, const char* utf8, const CHAR16_T* utf16) +{ + const size_t utf8Length = strlen(utf8); + const size_t utf16Length = utf16_length(utf16); + const bool invalid = has_replacement_char(utf16, utf16Length); + + CHECK(check_utf8_to_utf16(name, index, variant, utf8, utf8Length, utf16, utf16Length, invalid)); + return check_utf8_to_utf16(name, index, variant, utf8, utf8Length + 1, utf16, utf16Length + 1, invalid); +} + +// Embeds the string between ASCII runs long enough to take the fast paths, at every offset modulo 8 +static RESULT check_utf8_string_embedded(const char* name, size_t index, const char* utf8, const CHAR16_T* utf16) +{ + const size_t suffix = 16; + const size_t utf8Length = strlen(utf8); + const size_t utf16Length = utf16_length(utf16); + char longUtf8[128]; + CHAR16_T longUtf16[128]; + + for (size_t prefix = 14; prefix < 22; prefix++) + { + for (size_t j = 0; j < prefix; j++) + { + longUtf8[j] = (char)('a' + j % 26); + longUtf16[j] = (CHAR16_T)('a' + j % 26); + } + + memcpy(longUtf8 + prefix, utf8, utf8Length); + memcpy(longUtf16 + prefix, utf16, utf16Length * sizeof(CHAR16_T)); + + for (size_t j = 0; j < suffix; j++) + { + longUtf8[prefix + utf8Length + j] = (char)('A' + j); + longUtf16[prefix + utf16Length + j] = (CHAR16_T)('A' + j); + } + + longUtf8[prefix + utf8Length + suffix] = '\0'; + longUtf16[prefix + utf16Length + suffix] = 0; + + CHECK(check_utf8_string(name, index, prefix, longUtf8, longUtf16)); + } + + return OK; +} + +// Checks the size query, an exactly sized destination, destinations that are too small, MINIPAL_MB_NO_REPLACE_INVALID_CHARS +// and MINIPAL_TREAT_AS_LITTLE_ENDIAN for one input. The buffers have room for capacity bytes, more than expectedLength, +// and swapped for sourceLength code units. +static RESULT check_utf16_to_utf8_in(const char* name, size_t index, size_t variant, + const CHAR16_T* source, size_t sourceLength, const char* expected, size_t expectedLength, + char* native, char* little, CHAR16_T* swapped, size_t capacity) +{ + size_t count; + int error; + + errno = ERRNO_SENTINEL; + count = minipal_get_length_utf16_to_utf8(source, sourceLength, 0); + error = errno; + if (count != expectedLength || error != 0) + { + return FAILED("%s %zu.%zu: minipal_get_length_utf16_to_utf8 returned %zu with errno %d, expected %zu", + name, index, variant, count, error, expectedLength); + } + + // An exactly sized destination gets the whole string and nothing past it + memset(native, Utf8Canary, capacity); + errno = ERRNO_SENTINEL; + count = minipal_convert_utf16_to_utf8(source, sourceLength, native, expectedLength, 0); + error = errno; + if (count != expectedLength || error != 0 || memcmp(native, expected, expectedLength) != 0 || native[expectedLength] != Utf8Canary) + { + return FAILED("%s %zu.%zu: minipal_convert_utf16_to_utf8 returned %zu with errno %d, expected %zu, or produced an unexpected string", + name, index, variant, count, error, expectedLength); + } + + // Destinations that are too small fail without writing past their end + if (expectedLength != 0) + { + const size_t sizes[] = { expectedLength - 1, 0 }; + for (size_t s = 0; s < ARRAY_SIZE(sizes); s++) + { + memset(native, Utf8Canary, capacity); + count = minipal_convert_utf16_to_utf8(source, sourceLength, native, sizes[s], 0); + error = errno; + if (count != 0 || error != MINIPAL_ERROR_INSUFFICIENT_BUFFER || native[sizes[s]] != Utf8Canary) + { + return FAILED("%s %zu.%zu: minipal_convert_utf16_to_utf8 into %zu bytes returned %zu with errno %d, expected 0 with MINIPAL_ERROR_INSUFFICIENT_BUFFER and nothing written past them", + name, index, variant, sizes[s], count, error); + } + } + } + + // MINIPAL_MB_NO_REPLACE_INVALID_CHARS only applies to UTF-8 input, lone surrogates are always replaced + errno = ERRNO_SENTINEL; + count = minipal_get_length_utf16_to_utf8(source, sourceLength, MINIPAL_MB_NO_REPLACE_INVALID_CHARS); + error = errno; + if (count != expectedLength || error != 0) + { + return FAILED("%s %zu.%zu: minipal_get_length_utf16_to_utf8 with MINIPAL_MB_NO_REPLACE_INVALID_CHARS returned %zu with errno %d, expected %zu", + name, index, variant, count, error, expectedLength); + } + + memset(native, Utf8Canary, capacity); + errno = ERRNO_SENTINEL; + count = minipal_convert_utf16_to_utf8(source, sourceLength, native, capacity, MINIPAL_MB_NO_REPLACE_INVALID_CHARS); + error = errno; + if (count != expectedLength || error != 0 || memcmp(native, expected, expectedLength) != 0) + { + return FAILED("%s %zu.%zu: minipal_convert_utf16_to_utf8 with MINIPAL_MB_NO_REPLACE_INVALID_CHARS returned %zu with errno %d, expected %zu", + name, index, variant, count, error, expectedLength); + } + + // With MINIPAL_TREAT_AS_LITTLE_ENDIAN, the input with each code unit byte-swapped on big-endian platforms converts + // like the native input, and the flag changes nothing elsewhere, for any destination size + const bool bigEndian = is_big_endian(); + for (size_t i = 0; i < sourceLength; i++) + swapped[i] = bigEndian ? swap_bytes(source[i]) : source[i]; + + const unsigned int flagSets[] = { 0, MINIPAL_MB_NO_REPLACE_INVALID_CHARS }; + const size_t sizes[] = { expectedLength, expectedLength != 0 ? expectedLength - 1 : 0, capacity }; + for (size_t f = 0; f < ARRAY_SIZE(flagSets); f++) + { + const unsigned int flags = flagSets[f]; + + errno = ERRNO_SENTINEL; + size_t nativeCount = minipal_get_length_utf16_to_utf8(source, sourceLength, flags); + int nativeError = errno; + errno = ERRNO_SENTINEL; + size_t littleCount = minipal_get_length_utf16_to_utf8(swapped, sourceLength, flags | MINIPAL_TREAT_AS_LITTLE_ENDIAN); + int littleError = errno; + if (littleCount != nativeCount || littleError != nativeError) + { + return FAILED("%s %zu.%zu: minipal_get_length_utf16_to_utf8 with flags 0x%x returned %zu with errno %d for little-endian, %zu with errno %d otherwise", + name, index, variant, flags, littleCount, littleError, nativeCount, nativeError); + } + + for (size_t s = 0; s < ARRAY_SIZE(sizes); s++) + { + memset(native, Utf8Canary, capacity); + memset(little, Utf8Canary, capacity); + errno = ERRNO_SENTINEL; + nativeCount = minipal_convert_utf16_to_utf8(source, sourceLength, native, sizes[s], flags); + nativeError = errno; + errno = ERRNO_SENTINEL; + littleCount = minipal_convert_utf16_to_utf8(swapped, sourceLength, little, sizes[s], flags | MINIPAL_TREAT_AS_LITTLE_ENDIAN); + littleError = errno; + if (littleCount != nativeCount || littleError != nativeError || memcmp(little, native, nativeCount) != 0) + { + return FAILED("%s %zu.%zu: minipal_convert_utf16_to_utf8 with flags 0x%x into %zu bytes returned %zu with errno %d for little-endian, %zu with errno %d otherwise, or different bytes", + name, index, variant, flags, sizes[s], littleCount, littleError, nativeCount, nativeError); + } + } + } + + return OK; +} + +static RESULT check_utf16_to_utf8(const char* name, size_t index, size_t variant, + const CHAR16_T* source, size_t sourceLength, const char* expected, size_t expectedLength) +{ + const size_t capacity = expectedLength + 16; + char* native = (char*)malloc(capacity); + char* little = (char*)malloc(capacity); + CHAR16_T* swapped = (CHAR16_T*)malloc((sourceLength + 1) * sizeof(CHAR16_T)); + RESULT result = native != NULL && little != NULL && swapped != NULL + ? check_utf16_to_utf8_in(name, index, variant, source, sourceLength, expected, expectedLength, native, little, swapped, capacity) + : FAILED("%s %zu.%zu: out of memory", name, index, variant); + free(native); + free(little); + free(swapped); + return result; +} + +// Converts a NUL-terminated string without and with its terminator +static RESULT check_utf16_string(const char* name, size_t index, size_t variant, const CHAR16_T* utf16, const char* utf8) +{ + const size_t utf16Length = utf16_length(utf16); + const size_t utf8Length = strlen(utf8); + + CHECK(check_utf16_to_utf8(name, index, variant, utf16, utf16Length, utf8, utf8Length)); + return check_utf16_to_utf8(name, index, variant, utf16, utf16Length + 1, utf8, utf8Length + 1); +} + +// Embeds the string between ASCII runs long enough to take the fast paths, at every offset modulo 8 +static RESULT check_utf16_string_embedded(const char* name, size_t index, const CHAR16_T* utf16, const char* utf8) +{ + const size_t suffix = 16; + const size_t utf16Length = utf16_length(utf16); + const size_t utf8Length = strlen(utf8); + CHAR16_T longUtf16[128]; + char longUtf8[128]; + + for (size_t prefix = 14; prefix < 22; prefix++) + { + for (size_t j = 0; j < prefix; j++) + { + longUtf16[j] = (CHAR16_T)('a' + j % 26); + longUtf8[j] = (char)('a' + j % 26); + } + + memcpy(longUtf16 + prefix, utf16, utf16Length * sizeof(CHAR16_T)); + memcpy(longUtf8 + prefix, utf8, utf8Length); + + for (size_t j = 0; j < suffix; j++) + { + longUtf16[prefix + utf16Length + j] = (CHAR16_T)('A' + j); + longUtf8[prefix + utf8Length + j] = (char)('A' + j); + } + + longUtf16[prefix + utf16Length + suffix] = 0; + longUtf8[prefix + utf8Length + suffix] = '\0'; + + CHECK(check_utf16_string(name, index, prefix, longUtf16, longUtf8)); + } + + return OK; +} + +static uint32_t next_random(uint32_t* state) +{ + uint32_t x = *state; + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + return *state = x; +} + +static uint32_t random_code_point(uint32_t* state, uint32_t kind) +{ + uint32_t r = next_random(state); + switch (kind % 4) + { + case 0: + return r % 0x80; + case 1: + return 0x80 + r % (0x800 - 0x80); + case 2: + { + uint32_t codePoint = 0x800 + r % (0x10000 - 0x800 - 0x800); + return codePoint >= 0xD800 ? codePoint + 0x800 : codePoint; + } + default: + return 0x10000 + r % 0x100000; + } +} + +#define RANDOM_PIECES 24 +#define RANDOM_RUN 24 +#define RANDOM_UTF8_CAPACITY (RANDOM_PIECES * RANDOM_RUN * 4) + +// Runs of characters of one length, which the fast paths stay in, mixed with the kinds of ill-formed sequences that +// make them stop +static size_t random_utf8(uint32_t* state, char* buffer) +{ + static const unsigned char invalidLeads[] = { 0xC0, 0xC1, 0xE0, 0xED, 0xF0, 0xF4, 0xF5, 0xF8, 0xFE, 0xFF }; + unsigned char* p = (unsigned char*)buffer; + size_t length = 0; + size_t pieces = 1 + next_random(state) % RANDOM_PIECES; + + for (size_t piece = 0; piece < pieces; piece++) + { + uint32_t r = next_random(state); + size_t run = 1 + (r >> 8) % RANDOM_RUN; + switch (r % 8) + { + case 0: + case 1: + case 2: + case 3: + // a run of 1, 2, 3 or 4 byte encoded characters + for (size_t i = 0; i < run; i++) + length += reference_encode_utf8(random_code_point(state, r), p + length); + break; + case 4: + // characters of any length + for (size_t i = 0; i < run; i++) + length += reference_encode_utf8(random_code_point(state, next_random(state)), p + length); + break; + case 5: + // a byte that isn't ASCII + p[length++] = (unsigned char)(0x80 | next_random(state)); + break; + case 6: + { + // an incomplete 2, 3 or 4 byte encoded character + unsigned char sequence[4]; + size_t sequenceLength = reference_encode_utf8(random_code_point(state, 1 + next_random(state) % 3), sequence); + size_t keep = 1 + next_random(state) % (sequenceLength - 1); + memcpy(p + length, sequence, keep); + length += keep; + break; + } + default: + // a lead byte that is invalid or can start ill-formed sequences, followed by continuation bytes + p[length++] = invalidLeads[next_random(state) % ARRAY_SIZE(invalidLeads)]; + for (size_t i = 0; i < 3; i++) + p[length++] = (unsigned char)(0x80 | (next_random(state) % 0x40)); + break; + } + } + + return length; +} + +#define RANDOM_UTF16_CAPACITY (RANDOM_PIECES * RANDOM_RUN * 2) + +// Runs of characters of one UTF-8 length, which the fast paths stay in, mixed with lone surrogates +static size_t random_utf16(uint32_t* state, CHAR16_T* buffer) +{ + size_t length = 0; + size_t pieces = 1 + next_random(state) % RANDOM_PIECES; + + for (size_t piece = 0; piece < pieces; piece++) + { + uint32_t r = next_random(state); + size_t run = 1 + (r >> 8) % RANDOM_RUN; + switch (r % 8) + { + case 0: + case 1: + case 2: + case 3: + case 4: + // a run of characters of one UTF-8 length, or of any length + for (size_t i = 0; i < run; i++) + { + uint32_t codePoint = random_code_point(state, r % 8 == 4 ? next_random(state) : r); + if (codePoint >= 0x10000) + { + buffer[length++] = (CHAR16_T)(0xD800 + ((codePoint - 0x10000) >> 10)); + buffer[length++] = (CHAR16_T)(0xDC00 + (codePoint & 0x3FF)); + } + else + { + buffer[length++] = (CHAR16_T)codePoint; + } + } + break; + case 5: + // a lone high surrogate + buffer[length++] = (CHAR16_T)(0xD800 + next_random(state) % 0x400); + break; + case 6: + // a lone low surrogate + buffer[length++] = (CHAR16_T)(0xDC00 + next_random(state) % 0x400); + break; + default: + // a run of lone high surrogates + for (size_t i = 0; i < run; i++) + buffer[length++] = (CHAR16_T)(0xD800 + next_random(state) % 0x400); + break; + } + } + + return length; +} + +// Long runs of one kind of character, around the lengths where the UTF-16 counting flushes its per-lane counts +static const size_t long_run_lengths[] = { 4095, 4096, 4097, 16383, 16384, 16385, 32767, 32768, 32769, 32776, 65537 }; +#define LONG_RUN_KINDS 7 + +static void make_long_run(size_t kind, CHAR16_T* buffer, size_t length) +{ + for (size_t i = 0; i < length; i++) + { + switch (kind) + { + case 0: buffer[i] = (CHAR16_T)('a' + i % 26); break; + case 1: buffer[i] = 0x0080; break; + case 2: buffer[i] = (i % 2 == 0) ? (CHAR16_T)'A' : (CHAR16_T)0x07FF; break; + case 3: buffer[i] = 0x0800; break; + case 4: buffer[i] = (i % 2 == 0) ? (CHAR16_T)0xD83D : (CHAR16_T)0xDE00; break; + case 5: buffer[i] = (i % 3 == 0) ? (CHAR16_T)'A' : (i % 3 == 1) ? (CHAR16_T)0x07FF : (CHAR16_T)0xFFFF; break; + default: buffer[i] = (CHAR16_T)((i % 1000 == 999) ? 0xD800 : 0x00E9); break; + } + } +} + +static RESULT test_utf8_to_utf16_valid_strings(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(valid_strings); i++) + CHECK(check_utf8_string("valid string", i, 0, valid_strings[i].utf8, valid_strings[i].utf16)); + + return OK; +} + +static RESULT test_utf8_to_utf16_invalid_strings(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(invalid_utf8_strings); i++) + CHECK(check_utf8_string("invalid string", i, 0, invalid_utf8_strings[i].utf8, invalid_utf8_strings[i].utf16)); + + return OK; +} + +static RESULT test_utf8_to_utf16_long_strings(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(valid_strings); i++) + CHECK(check_utf8_string_embedded("long valid string", i, valid_strings[i].utf8, valid_strings[i].utf16)); + + for (size_t i = 0; i < ARRAY_SIZE(invalid_utf8_strings); i++) + CHECK(check_utf8_string_embedded("long invalid string", i, invalid_utf8_strings[i].utf8, invalid_utf8_strings[i].utf16)); + + return OK; +} + +static RESULT test_utf8_to_utf16_embedded_nuls(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(utf8_strings_with_nuls); i++) + { + const CountedStringPair* pair = &utf8_strings_with_nuls[i]; + CHECK(check_utf8_to_utf16("string with NULs", i, 0, pair->utf8, pair->utf8Length, pair->utf16, pair->utf16Length, + has_replacement_char(pair->utf16, pair->utf16Length))); + } + + return OK; +} + +static RESULT test_utf8_to_utf16_long_runs(void) +{ + const size_t maxLength = long_run_lengths[ARRAY_SIZE(long_run_lengths) - 1]; + CHAR16_T* utf16 = (CHAR16_T*)malloc(maxLength * sizeof(CHAR16_T)); + CHAR16_T* expected = (CHAR16_T*)malloc(maxLength * sizeof(CHAR16_T)); + char* utf8 = (char*)malloc(maxLength * 3); + RESULT result = utf16 != NULL && expected != NULL && utf8 != NULL ? OK : FAILED("out of memory"); + + for (size_t kind = 0; kind < LONG_RUN_KINDS && result == OK; kind++) + { + for (size_t i = 0; i < ARRAY_SIZE(long_run_lengths) && result == OK; i++) + { + bool invalid; + make_long_run(kind, utf16, long_run_lengths[i]); + size_t utf8Length = reference_utf16_to_utf8(utf16, long_run_lengths[i], utf8); + size_t expectedLength = reference_utf8_to_utf16(utf8, utf8Length, expected, &invalid); + result = check_utf8_to_utf16("long run", kind, long_run_lengths[i], utf8, utf8Length, expected, expectedLength, invalid); + } + } + + free(utf16); + free(expected); + free(utf8); + return result; +} + +// Random input checked against the reference model +static RESULT test_utf8_to_utf16_random(void) +{ + uint32_t state = 0x2545F491; + char* source = (char*)malloc(RANDOM_UTF8_CAPACITY); + CHAR16_T* expected = (CHAR16_T*)malloc(RANDOM_UTF8_CAPACITY * sizeof(CHAR16_T)); + RESULT result = source != NULL && expected != NULL ? OK : FAILED("out of memory"); + + for (size_t i = 0; i < 2000 && result == OK; i++) + { + bool invalid; + size_t sourceLength = random_utf8(&state, source); + size_t expectedLength = reference_utf8_to_utf16(source, sourceLength, expected, &invalid); + result = check_utf8_to_utf16("random string", i, 0, source, sourceLength, expected, expectedLength, invalid); + } + + free(source); + free(expected); + return result; +} + +static RESULT test_utf16_to_utf8_valid_strings(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(valid_strings); i++) + CHECK(check_utf16_string("valid string", i, 0, valid_strings[i].utf16, valid_strings[i].utf8)); + + return OK; +} + +static RESULT test_utf16_to_utf8_invalid_strings(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(invalid_utf16_strings); i++) + CHECK(check_utf16_string("invalid string", i, 0, invalid_utf16_strings[i].utf16, invalid_utf16_strings[i].utf8)); + + return OK; +} + +static RESULT test_utf16_to_utf8_long_strings(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(valid_strings); i++) + CHECK(check_utf16_string_embedded("long valid string", i, valid_strings[i].utf16, valid_strings[i].utf8)); + + for (size_t i = 0; i < ARRAY_SIZE(invalid_utf16_strings); i++) + CHECK(check_utf16_string_embedded("long invalid string", i, invalid_utf16_strings[i].utf16, invalid_utf16_strings[i].utf8)); + + return OK; +} + +static RESULT test_utf16_to_utf8_embedded_nuls(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(utf16_strings_with_nuls); i++) + { + const CountedStringPair* pair = &utf16_strings_with_nuls[i]; + CHECK(check_utf16_to_utf8("string with NULs", i, 0, pair->utf16, pair->utf16Length, pair->utf8, pair->utf8Length)); + } + + return OK; +} + +static RESULT test_utf16_to_utf8_long_runs(void) +{ + const size_t maxLength = long_run_lengths[ARRAY_SIZE(long_run_lengths) - 1]; + CHAR16_T* utf16 = (CHAR16_T*)malloc(maxLength * sizeof(CHAR16_T)); + char* expected = (char*)malloc(maxLength * 3); + RESULT result = utf16 != NULL && expected != NULL ? OK : FAILED("out of memory"); + + for (size_t kind = 0; kind < LONG_RUN_KINDS && result == OK; kind++) + { + for (size_t i = 0; i < ARRAY_SIZE(long_run_lengths) && result == OK; i++) + { + make_long_run(kind, utf16, long_run_lengths[i]); + size_t expectedLength = reference_utf16_to_utf8(utf16, long_run_lengths[i], expected); + result = check_utf16_to_utf8("long run", kind, long_run_lengths[i], utf16, long_run_lengths[i], expected, expectedLength); + } + } + + free(utf16); + free(expected); + return result; +} + +// Random input checked against the reference model +static RESULT test_utf16_to_utf8_random(void) +{ + uint32_t state = 0x9E3779B9; + CHAR16_T* source = (CHAR16_T*)malloc(RANDOM_UTF16_CAPACITY * sizeof(CHAR16_T)); + char* expected = (char*)malloc(RANDOM_UTF16_CAPACITY * 3); + RESULT result = source != NULL && expected != NULL ? OK : FAILED("out of memory"); + + for (size_t i = 0; i < 2000 && result == OK; i++) + { + size_t sourceLength = random_utf16(&state, source); + size_t expectedLength = reference_utf16_to_utf8(source, sourceLength, expected); + result = check_utf16_to_utf8("random string", i, 0, source, sourceLength, expected, expectedLength); + } + + free(source); + free(expected); + return result; +} + +static Test minipal_utf8_tests[] = +{ + {"test_utf8_to_utf16_valid_strings", test_utf8_to_utf16_valid_strings}, + {"test_utf8_to_utf16_invalid_strings", test_utf8_to_utf16_invalid_strings}, + {"test_utf8_to_utf16_long_strings", test_utf8_to_utf16_long_strings}, + {"test_utf8_to_utf16_embedded_nuls", test_utf8_to_utf16_embedded_nuls}, + {"test_utf8_to_utf16_long_runs", test_utf8_to_utf16_long_runs}, + {"test_utf8_to_utf16_random", test_utf8_to_utf16_random}, + {"test_utf16_to_utf8_valid_strings", test_utf16_to_utf8_valid_strings}, + {"test_utf16_to_utf8_invalid_strings", test_utf16_to_utf8_invalid_strings}, + {"test_utf16_to_utf8_long_strings", test_utf16_to_utf8_long_strings}, + {"test_utf16_to_utf8_embedded_nuls", test_utf16_to_utf8_embedded_nuls}, + {"test_utf16_to_utf8_long_runs", test_utf16_to_utf8_long_runs}, + {"test_utf16_to_utf8_random", test_utf16_to_utf8_random}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(minipal_utf8_tests_init, minipal_utf8_tests) From 7b6b34e5db458b7fe9637c6a2cd40af868e59819 Mon Sep 17 00:00:00 2001 From: am11 <3840695+am11@users.noreply.github.com> Date: Wed, 4 Nov 2026 19:48:08 +0200 Subject: [PATCH 02/13] Use the minipal UTF-8 conversions instead of MultiByteToWideChar and WideCharToMultiByte Call minipal_get_length_* and minipal_convert_* directly for every conversion in CoreCLR, on Windows as well as Unix, including the PAL, the PAL test helpers and the generated LTTng provider. Native code now treats narrow strings as UTF-8 everywhere instead of using the ANSI or console code page on Windows: console output of ilasm, ildasm and PrintToStdErrW, metadata, ETW and config names, the ildasm input file name, the dbghelp symbol path, GC config strings, the mcs command line and the assembly name hashed into the typelib GUID. ilasm opens resource files by their UTF-16 name instead of converting it. Callers that pass a destination size of 0 now ask for the length explicitly, which fixes GetVersionString writing past the caller's buffer on Unix. Also pass EventStaticEntry::WriteEntry a size in characters rather than bytes, and keep the terminator inside the buffer in the GDB JIT file names. --- src/coreclr/debug/daccess/daccess.cpp | 26 +++++----- src/coreclr/debug/di/rsmain.cpp | 10 ++-- src/coreclr/debug/ee/debugger.cpp | 8 +-- src/coreclr/dlls/mscoree/exports.cpp | 5 +- src/coreclr/hosts/corerun/corerun.hpp | 11 +++-- src/coreclr/ilasm/asmman.cpp | 14 +++--- src/coreclr/ilasm/asmparse.h | 5 +- src/coreclr/ilasm/assem.cpp | 19 ++++--- src/coreclr/ilasm/assembler.cpp | 12 ++--- src/coreclr/ilasm/class.hpp | 2 +- src/coreclr/ilasm/grammar_after.cpp | 15 ++---- src/coreclr/ilasm/grammar_before.cpp | 2 - src/coreclr/ilasm/main.cpp | 18 +++---- src/coreclr/ilasm/method.hpp | 2 +- src/coreclr/ilasm/typar.hpp | 4 +- src/coreclr/ilasm/writer.cpp | 13 ++--- src/coreclr/ildasm/dasm.cpp | 16 +++--- src/coreclr/ildasm/dis.cpp | 12 ++--- src/coreclr/ildasm/dman.cpp | 22 ++++----- src/coreclr/ildasm/windasm.cpp | 6 +-- src/coreclr/inc/mdfileformat.h | 6 +-- src/coreclr/inc/utilcode.h | 49 ++++++++----------- src/coreclr/jit/utils.cpp | 20 ++------ src/coreclr/md/compiler/custattr_import.cpp | 6 ++- src/coreclr/md/compiler/disp.cpp | 5 +- src/coreclr/md/compiler/import.cpp | 27 ++++++---- src/coreclr/md/enc/metamodelrw.cpp | 17 +++---- src/coreclr/md/enc/rwutil.cpp | 16 ++---- src/coreclr/md/enc/stgtiggerstorage.cpp | 6 +-- src/coreclr/md/runtime/metamodelro.cpp | 16 +++--- src/coreclr/md/runtime/stgpool.cpp | 26 ++-------- .../nativeaot/Runtime/windows/PalCommon.cpp | 13 ++--- .../nativeaot/Runtime/windows/PalMinWin.cpp | 12 ++--- .../nativeresources/resourcestring.cpp | 9 ++-- src/coreclr/pal/src/cruntime/wchar.cpp | 18 +++---- src/coreclr/pal/src/debug/debug.cpp | 8 +-- src/coreclr/pal/src/file/directory.cpp | 13 ++--- src/coreclr/pal/src/file/file.cpp | 4 +- src/coreclr/pal/src/file/path.cpp | 25 ++++------ src/coreclr/pal/src/include/pal/utils.h | 4 +- src/coreclr/pal/src/init/pal.cpp | 6 +-- src/coreclr/pal/src/loader/module.cpp | 7 ++- src/coreclr/pal/src/misc/environ.cpp | 25 ++++------ src/coreclr/pal/src/misc/fmtmessage.cpp | 4 +- src/coreclr/pal/src/misc/utils.cpp | 19 ++++--- src/coreclr/pal/src/thread/thread.cpp | 5 +- .../pal/tests/palsuite/common/palsuite.cpp | 18 +++---- src/coreclr/scripts/genLttngProvider.py | 7 +-- src/coreclr/tools/metainfo/mdinfo.cpp | 4 +- src/coreclr/tools/metainfo/mdobj.cpp | 3 +- src/coreclr/tools/superpmi/mcs/verbmerge.cpp | 40 +++++++-------- src/coreclr/tools/superpmi/mcs/verbmerge.h | 4 +- .../superpmi/superpmi-shared/spmiutil.cpp | 8 +-- .../tools/superpmi/superpmi/jithost.cpp | 32 +++--------- src/coreclr/utilcode/fstring.cpp | 42 +++++----------- src/coreclr/utilcode/sstring.cpp | 26 ++++------ src/coreclr/utilcode/stacktrace.cpp | 9 ++-- src/coreclr/utilcode/util.cpp | 7 +-- src/coreclr/vm/assemblyspec.cpp | 9 ++-- src/coreclr/vm/cdacstress.cpp | 4 +- src/coreclr/vm/commtmemberinfomap.cpp | 5 +- src/coreclr/vm/dllimport.cpp | 3 +- src/coreclr/vm/dwbucketmanager.hpp | 7 +-- src/coreclr/vm/eventtracepriv.h | 11 ++--- src/coreclr/vm/gcenv.ee.cpp | 20 ++++---- src/coreclr/vm/gctoclreventsink.cpp | 2 +- src/coreclr/vm/gdbjit.cpp | 16 +++--- src/coreclr/vm/interoputil.cpp | 4 +- src/coreclr/vm/object.cpp | 4 +- src/coreclr/vm/util.cpp | 14 ++---- src/native/minipal/utf8.h | 13 +++-- 71 files changed, 395 insertions(+), 505 deletions(-) diff --git a/src/coreclr/debug/daccess/daccess.cpp b/src/coreclr/debug/daccess/daccess.cpp index 75b6e12844faa4..9604467fa9af52 100644 --- a/src/coreclr/debug/daccess/daccess.cpp +++ b/src/coreclr/debug/daccess/daccess.cpp @@ -95,20 +95,18 @@ ConvertUtf8(_In_ LPCUTF8 utf8, ULONG32* nameLen, _Out_writes_to_opt_(bufLen, *nameLen) PWSTR buffer) { + size_t cchUtf8 = strlen(utf8) + 1; + if (nameLen) { - *nameLen = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0); - if (!*nameLen) - { - return HRESULT_FROM_GetLastError(); - } + *nameLen = (ULONG32)minipal_get_length_utf8_to_utf16(utf8, cchUtf8, 0); } if (buffer && bufLen) { - if (!MultiByteToWideChar(CP_UTF8, 0, utf8, -1, buffer, bufLen)) + if (!minipal_convert_utf8_to_utf16(utf8, cchUtf8, (CHAR16_T*)buffer, bufLen, 0)) { - return HRESULT_FROM_GetLastError(); + return HRESULT_FROM_WIN32(errno); } } @@ -120,13 +118,14 @@ AllocUtf8(_In_opt_ LPCWSTR wstr, ULONG32 srcChars, _Outptr_ LPUTF8* utf8) { - ULONG32 chars = WideCharToMultiByte(CP_UTF8, 0, wstr, srcChars, - NULL, 0, NULL, NULL); - if (!chars) + if (wstr == NULL || srcChars == 0) { - return HRESULT_FROM_GetLastError(); + return E_INVALIDARG; } + size_t cchSrc = srcChars == (ULONG32)-1 ? u16_strlen(wstr) + 1 : srcChars; + ULONG32 chars = (ULONG32)minipal_get_length_utf16_to_utf8((const CHAR16_T*)wstr, cchSrc, 0); + // Make sure the converted string is always terminated. if (srcChars != (ULONG32)-1) { @@ -142,10 +141,9 @@ AllocUtf8(_In_opt_ LPCWSTR wstr, return E_OUTOFMEMORY; } - if (!WideCharToMultiByte(CP_UTF8, 0, wstr, srcChars, - mem, chars, NULL, NULL)) + if (!minipal_convert_utf16_to_utf8((const CHAR16_T*)wstr, cchSrc, mem, chars, 0)) { - HRESULT hr = HRESULT_FROM_GetLastError(); + HRESULT hr = HRESULT_FROM_WIN32(errno); delete [] mem; return hr; } diff --git a/src/coreclr/debug/di/rsmain.cpp b/src/coreclr/debug/di/rsmain.cpp index d41431301322fb..4b0a5ce52a7b3f 100644 --- a/src/coreclr/debug/di/rsmain.cpp +++ b/src/coreclr/debug/di/rsmain.cpp @@ -1873,11 +1873,8 @@ HRESULT Cordb::CreateObject(CorDebugInterfaceVersion iDebuggerVersion, DWORD pid if (lpApplicationGroupId != NULL) { // Get length of target string - int cbMultiByte = WideCharToMultiByte(CP_ACP, 0, lpApplicationGroupId, -1, NULL, 0, NULL, NULL); - if (cbMultiByte == 0) - { - return E_FAIL; - } + size_t cchApplicationGroupId = u16_strlen(lpApplicationGroupId) + 1; + size_t cbMultiByte = minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpApplicationGroupId, cchApplicationGroupId, 0); applicationGroupId = new (nothrow) CHAR[cbMultiByte]; if (applicationGroupId == NULL) @@ -1885,8 +1882,7 @@ HRESULT Cordb::CreateObject(CorDebugInterfaceVersion iDebuggerVersion, DWORD pid return (E_OUTOFMEMORY); } - /* Convert to ASCII */ - cbMultiByte = WideCharToMultiByte(CP_ACP, 0, lpApplicationGroupId, -1, applicationGroupId, cbMultiByte, NULL, NULL); + cbMultiByte = minipal_convert_utf16_to_utf8((const CHAR16_T*)lpApplicationGroupId, cchApplicationGroupId, applicationGroupId, cbMultiByte, 0); if (cbMultiByte == 0) { delete [] applicationGroupId; diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index 66549ac11986d2..7b08ba85b4e5a5 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -920,8 +920,10 @@ void Debugger::InitDebugEventCounting() if (wstrValue != NULL) { LPSTR strValue; - int cbReq; - cbReq = WideCharToMultiByte(CP_UTF8, 0, wstrValue,-1, 0,0, 0,0); + size_t cbReq; + const CHAR16_T* wszValue = (const CHAR16_T*)(LPWSTR)wstrValue; + size_t cchValue = u16_strlen(wstrValue) + 1; + cbReq = minipal_get_length_utf16_to_utf8(wszValue, cchValue, 0); strValue = new (nothrow) char[cbReq+1]; // This is a debug only thingy, if it fails, not worth taking @@ -931,7 +933,7 @@ void Debugger::InitDebugEventCounting() // now translate the unicode to ansi string - WideCharToMultiByte(CP_UTF8, 0, wstrValue, -1, strValue, cbReq+1, 0,0); + minipal_convert_utf16_to_utf8(wszValue, cchValue, strValue, cbReq+1, 0); char *szEnd = (char *)strchr(strValue, ';'); char *szStart = strValue; while (szEnd != NULL) diff --git a/src/coreclr/dlls/mscoree/exports.cpp b/src/coreclr/dlls/mscoree/exports.cpp index 03c28668f04b97..75ae2bd3708b34 100644 --- a/src/coreclr/dlls/mscoree/exports.cpp +++ b/src/coreclr/dlls/mscoree/exports.cpp @@ -120,13 +120,14 @@ struct HostPropertyArraysTraits final // Convert 8 bit string to unicode static LPCWSTR StringToUnicode(LPCSTR str) { - int length = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); + size_t cch = strlen(str) + 1; + size_t length = minipal_get_length_utf8_to_utf16(str, cch, 0); ASSERTE_ALL_BUILDS(length != 0); LPWSTR result = new (nothrow) WCHAR[length]; ASSERTE_ALL_BUILDS(result != NULL); - length = MultiByteToWideChar(CP_UTF8, 0, str, -1, result, length); + length = minipal_convert_utf8_to_utf16(str, cch, (CHAR16_T*)result, length, 0); ASSERTE_ALL_BUILDS(length != 0); return result; diff --git a/src/coreclr/hosts/corerun/corerun.hpp b/src/coreclr/hosts/corerun/corerun.hpp index 0cfdd44be9620f..ea0fff64883d1a 100644 --- a/src/coreclr/hosts/corerun/corerun.hpp +++ b/src/coreclr/hosts/corerun/corerun.hpp @@ -16,6 +16,7 @@ #include #include #include +#include // Class used to perform specific actions. class platform_specific_actions; @@ -211,12 +212,13 @@ namespace pal inline string_utf8_t convert_to_utf8(const char_t* str) { - int bytes_req = ::WideCharToMultiByte(CP_UTF8, 0, str, -1, nullptr, 0, nullptr, nullptr); + size_t length = ::wcslen(str) + 1; + size_t bytes_req = minipal_get_length_utf16_to_utf8((const CHAR16_T*)str, length, 0); malloc_ptr buffer{ (char*)::malloc(bytes_req) }; assert(buffer != nullptr); - int written = ::WideCharToMultiByte(CP_UTF8, 0, str, -1, buffer.get(), bytes_req, nullptr, nullptr); + size_t written = minipal_convert_utf16_to_utf8((const CHAR16_T*)str, length, buffer.get(), bytes_req, 0); assert(bytes_req == written); return { buffer.get() }; @@ -224,12 +226,13 @@ namespace pal inline string_t convert_from_utf8(const char* str) { - int wchar_req = ::MultiByteToWideChar(CP_UTF8, 0, str, -1, nullptr, 0); + size_t length = ::strlen(str) + 1; + size_t wchar_req = minipal_get_length_utf8_to_utf16(str, length, 0); malloc_ptr buffer{ (wchar_t*)::malloc(wchar_req * sizeof(wchar_t)) }; assert(buffer != nullptr); - int written = ::MultiByteToWideChar(CP_UTF8, 0, str, -1, buffer.get(), wchar_req); + size_t written = minipal_convert_utf8_to_utf16(str, length, (CHAR16_T*)buffer.get(), wchar_req, 0); assert(wchar_req == written); return { buffer.get() }; diff --git a/src/coreclr/ilasm/asmman.cpp b/src/coreclr/ilasm/asmman.cpp index fcd3a71c9b4542..d8d5264e365d31 100644 --- a/src/coreclr/ilasm/asmman.cpp +++ b/src/coreclr/ilasm/asmman.cpp @@ -28,7 +28,7 @@ BinStr* BinStrToUnicode(BinStr* pSource, bool Swap) if(wz) { memset(wz,0,L); - MultiByteToWideChar(g_uCodePage,0,pb,-1,wz,l); + minipal_convert_utf8_to_utf16(pb,strlen(pb)+1,(CHAR16_T*)wz,l,0); tmp->remove(L-(DWORD)u16_strlen(wz)*sizeof(WCHAR)); #if BIGENDIAN if (Swap) @@ -205,7 +205,7 @@ void AsmMan::EmitFiles() if(!tmp->m_fNew) continue; tmp->m_fNew = FALSE; - MultiByteToWideChar(g_uCodePage,0,tmp->szName,-1,wzUniBuf,dwUniBuf); + minipal_convert_utf8_to_utf16(tmp->szName,strlen(tmp->szName)+1,(CHAR16_T*)wzUniBuf,dwUniBuf,0); if(tmp->pHash==NULL) // if hash not explicitly specified { if(m_pAssembly // and assembly is defined @@ -553,7 +553,7 @@ void AsmMan::EmitAssemblyRefs() dwFlags |= afPublicKey; } // Convert name to Unicode - MultiByteToWideChar(g_uCodePage,0,m_pCurAsmRef->szName,-1,wzUniBuf,dwUniBuf); + minipal_convert_utf8_to_utf16(m_pCurAsmRef->szName,strlen(m_pCurAsmRef->szName)+1,(CHAR16_T*)wzUniBuf,dwUniBuf,0); hr = m_pAsmEmitter->DefineAssemblyRef( // S_OK or error. pbPublicKeyOrToken, // [IN] Public key or token of the assembly. cbPublicKeyOrToken, // [IN] Count of bytes in the key or token. @@ -588,7 +588,7 @@ void AsmMan::EmitAssembly() FillAssemblyMetadata(m_pAssembly, &md); // Convert name to Unicode - MultiByteToWideChar(g_uCodePage,0,m_pAssembly->szName,-1,wzUniBuf,dwUniBuf); + minipal_convert_utf8_to_utf16(m_pAssembly->szName,strlen(m_pAssembly->szName)+1,(CHAR16_T*)wzUniBuf,dwUniBuf,0); hr = m_pAsmEmitter->DefineAssembly( // S_OK or error. (const void*)(m_sStrongName.m_pbPublicKey), // [IN] Public key of the assembly. @@ -857,7 +857,7 @@ HRESULT AsmMan::EmitManifest() if(!pComType->m_fNew) continue; pComType->m_fNew = FALSE; - MultiByteToWideChar(g_uCodePage,0,pComType->szName,-1,wzUniBuf,dwUniBuf); + minipal_convert_utf8_to_utf16(pComType->szName,strlen(pComType->szName)+1,(CHAR16_T*)wzUniBuf,dwUniBuf,0); mdToken tkImplementation = mdTokenNil; if(pComType->tkImpl) tkImplementation = pComType->tkImpl; else if(pComType->szFileName) @@ -930,7 +930,7 @@ HRESULT AsmMan::EmitManifest() if(!pManRes->m_fNew) continue; pManRes->m_fNew = FALSE; - MultiByteToWideChar(g_uCodePage,0,pManRes->szAlias,-1,wzUniBuf,dwUniBuf); + minipal_convert_utf8_to_utf16(pManRes->szAlias,strlen(pManRes->szAlias)+1,(CHAR16_T*)wzUniBuf,dwUniBuf,0); if(pManRes->szAsmRefName) { tkImplementation = GetAsmRefTokByName(pManRes->szAsmRefName); @@ -1007,7 +1007,7 @@ HRESULT AsmMan::EmitManifest() } if(fOK || ((Assembler*)m_pAssembler)->OnErrGo) { - MultiByteToWideChar(g_uCodePage,0,pManRes->szName,-1,wzUniBuf,dwUniBuf); + minipal_convert_utf8_to_utf16(pManRes->szName,strlen(pManRes->szName)+1,(CHAR16_T*)wzUniBuf,dwUniBuf,0); hr = m_pAsmEmitter->DefineManifestResource( // S_OK or error. (LPCWSTR)wzUniBuf, // [IN] Name of the resource. tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the resource. diff --git a/src/coreclr/ilasm/asmparse.h b/src/coreclr/ilasm/asmparse.h index a20157e83132d8..a037e107982809 100644 --- a/src/coreclr/ilasm/asmparse.h +++ b/src/coreclr/ilasm/asmparse.h @@ -105,9 +105,10 @@ class MappedFileStream : public ReadStream { if (IsValid()) { - int len = WideCharToMultiByte(CP_UTF8,0,wFileName,-1,NULL,0,NULL,NULL); + size_t cch = u16_strlen(wFileName)+1; + size_t len = minipal_get_length_utf16_to_utf8((const CHAR16_T*)wFileName,cch,0); m_fileNameUtf8 = new char[len+1]; - WideCharToMultiByte(CP_UTF8,0,wFileName,-1,m_fileNameUtf8,len+1,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wFileName,cch,m_fileNameUtf8,len+1,0); } } ~MappedFileStream() diff --git a/src/coreclr/ilasm/assem.cpp b/src/coreclr/ilasm/assem.cpp index 912ab2f3c9b2b3..63cc4a68a0fc16 100644 --- a/src/coreclr/ilasm/assem.cpp +++ b/src/coreclr/ilasm/assem.cpp @@ -22,7 +22,6 @@ void indexKeywords(Indx* indx); // defined in asmparse.y unsigned int g_uCodePage = CP_ACP; -unsigned int g_uConsoleCP = CP_ACP; char g_szSourceFileName[MAX_FILENAME_LENGTH*3]; @@ -605,7 +604,7 @@ void Assembler::EmitImports() mdToken tk; for(i=0; (pID = m_ImportList.PEEK(i)); i++) { - MultiByteToWideChar(g_uCodePage,0,pID->szDllName,-1,wzDllName,dwUniBuf-1); + minipal_convert_utf8_to_utf16(pID->szDllName,strlen(pID->szDllName)+1,(CHAR16_T*)wzDllName,dwUniBuf-1,0); if(FAILED(m_pEmitter->DefineModuleRef( // S_OK or error. wzDllName, // [IN] DLL name &tk))) // [OUT] returned @@ -619,7 +618,7 @@ HRESULT Assembler::EmitPinvokeMap(mdToken tk, PInvokeDescriptor* pDescr) { WCHAR* wzAlias=&wzUniBuf[0]; - if(pDescr->szAlias) MultiByteToWideChar(g_uCodePage,0,pDescr->szAlias,-1,wzAlias,dwUniBuf-1); + if(pDescr->szAlias) minipal_convert_utf8_to_utf16(pDescr->szAlias,strlen(pDescr->szAlias)+1,(CHAR16_T*)wzAlias,dwUniBuf-1,0); return m_pEmitter->DefinePinvokeMap( // Return code. tk, // [IN] FieldDef, MethodDef or MethodImpl. @@ -657,7 +656,7 @@ BOOL Assembler::EmitMethod(Method *pMethod) ClassToken = (pMethod->IsGlobalMethod())? mdTokenNil : pMethod->m_pClass->m_cl; // Convert name to UNICODE - MultiByteToWideChar(g_uCodePage,0,pszMethodName,-1,wzMemberName,dwUniBuf-1); + minipal_convert_utf8_to_utf16(pszMethodName,strlen(pszMethodName)+1,(CHAR16_T*)wzMemberName,dwUniBuf-1,0); if(IsMdPrivateScope(pMethod->m_Attr)) { @@ -801,7 +800,7 @@ BOOL Assembler::EmitMethod(Method *pMethod) if(pAN->dwName) strcpy_s(szPhonyName,dwUniBuf >> 1,pAN->szName); else sprintf_s(szPhonyName,(dwUniBuf >> 1),"A_%d",pAN->nNum); - MultiByteToWideChar(g_uCodePage,0,szPhonyName,-1,wzParName,dwUniBuf >> 1); + minipal_convert_utf8_to_utf16(szPhonyName,strlen(szPhonyName)+1,(CHAR16_T*)wzParName,dwUniBuf >> 1,0); if(pAN->pValue) { @@ -904,7 +903,7 @@ BOOL Assembler::EmitEvent(EventDescriptor* pED) if(!pED) return FALSE; - MultiByteToWideChar(g_uCodePage,0,pED->m_szName,-1,wzMemberName,dwUniBuf-1); + minipal_convert_utf8_to_utf16(pED->m_szName,strlen(pED->m_szName)+1,(CHAR16_T*)wzMemberName,dwUniBuf-1,0); mdAddOn = ResolveLocalMemberRef(pED->m_tkAddOn); if(TypeFromToken(mdAddOn) != mdtMethodDef) @@ -964,7 +963,7 @@ BOOL Assembler::EmitProp(PropDescriptor* pPD) if(!pPD) return FALSE; - MultiByteToWideChar(g_uCodePage,0,pPD->m_szName,-1,wzMemberName,dwUniBuf-1); + minipal_convert_utf8_to_utf16(pPD->m_szName,strlen(pPD->m_szName)+1,(CHAR16_T*)wzMemberName,dwUniBuf-1,0); mdSet = ResolveLocalMemberRef(pPD->m_tkSet); if((RidFromToken(mdSet)!=0)&&(TypeFromToken(mdSet) != mdtMethodDef)) @@ -1091,7 +1090,7 @@ BOOL Assembler::EmitClass(Class *pClass) else szFullName = pClass->m_szFQN; - MultiByteToWideChar(g_uCodePage,0,szFullName,-1,wzFullName,dwUniBuf); + minipal_convert_utf8_to_utf16(szFullName,strlen(szFullName)+1,(CHAR16_T*)wzFullName,dwUniBuf,0); L = u16_strlen(wzFullName); if((L==0)||(wzFullName[L-1]==L'.')) // Missing class name! @@ -1364,7 +1363,7 @@ char* Assembler::ReflectionNotation(mdToken tk) mdToken tkResScope; if(SUCCEEDED(m_pImporter->GetTypeRefProps(tk,&tkResScope,wzUniBuf,cchUniBuf,&N))) { - int ret = WideCharToMultiByte(CP_UTF8,0,wzUniBuf,-1,sz,szSizeBytes,NULL,NULL); + int ret = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)wzUniBuf,u16_strlen(wzUniBuf)+1,sz,szSizeBytes,0); if(TypeFromToken(tkResScope)==mdtAssemblyRef) { AsmManAssembly *pAsmRef = m_pManifest->m_AsmRefLst.PEEK(RidFromToken(tkResScope)-1); @@ -1403,7 +1402,7 @@ char* Assembler::ReflectionNotation(mdToken tk) { memcpy(wzUniBuf,pAsmRef->pLocale->ptr(),L); wzUniBuf[L>>1] = 0; - ret = WideCharToMultiByte(CP_UTF8,0,wzUniBuf,-1,pc,(int)szRemainingSizeBytes,NULL,NULL); + ret = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)wzUniBuf,u16_strlen(wzUniBuf)+1,pc,szRemainingSizeBytes,0); if (ret <= 0) { report->error("Locale too long.\n"); diff --git a/src/coreclr/ilasm/assembler.cpp b/src/coreclr/ilasm/assembler.cpp index 5096bbdda453fa..3a47286d42dd5c 100644 --- a/src/coreclr/ilasm/assembler.cpp +++ b/src/coreclr/ilasm/assembler.cpp @@ -373,7 +373,7 @@ mdToken Assembler::MakeTypeRef(mdToken tkResScope, LPCUTF8 pszFullClassName) if(*pc) { // convert name to widechar - MultiByteToWideChar(g_uCodePage,0,pc,-1,wzUniBuf,dwUniBuf); + minipal_convert_utf8_to_utf16(pc,strlen(pc)+1,(CHAR16_T*)wzUniBuf,dwUniBuf,0); if(FAILED(m_pEmitter->DefineTypeRefByName(tkResScope, wzUniBuf, &tkRet))) tkRet = mdTokenNil; } } @@ -910,7 +910,7 @@ BOOL Assembler::EmitField(FieldDescriptor* pFD) cSig = pFD->m_pbsSig->length(); mySig = (COR_SIGNATURE*)(pFD->m_pbsSig->ptr()); - MultiByteToWideChar(g_uCodePage,0,pFD->m_szName,-1,wzFieldName,dwUniBuf); //int)cFieldNameLength); + minipal_convert_utf8_to_utf16(pFD->m_szName,strlen(pFD->m_szName)+1,(CHAR16_T*)wzFieldName,dwUniBuf,0); //int)cFieldNameLength); if(IsFdPrivateScope(pFD->m_dwAttr)) { WCHAR* p = (WCHAR*)u16_strstr(wzFieldName,W("$PST04")); @@ -1368,7 +1368,7 @@ void Assembler::EmitDataString(BinStr* str) if(UnicodeString) { - MultiByteToWideChar(g_uCodePage,0,pb,-1,UnicodeString,DataLen); + minipal_convert_utf8_to_utf16(pb,strlen(pb)+1,(CHAR16_T*)UnicodeString,DataLen,0); EmitData(UnicodeString,DataLen*sizeof(WCHAR)); if(DataLen >= dwUniBuf) delete [] UnicodeString; } @@ -1777,7 +1777,7 @@ mdToken Assembler::MakeMemberRef(mdToken cr, _In_ __nullterminated char* pszMemb } else { - MultiByteToWideChar(g_uCodePage,0,pszMemberName,-1,wzUniBuf,dwUniBuf); + minipal_convert_utf8_to_utf16(pszMemberName,strlen(pszMemberName)+1,(CHAR16_T*)wzUniBuf,dwUniBuf,0); if(cr == mdTokenNil) cr = mdTypeRefNil; if(TypeFromToken(cr) == mdtAssemblyRef) @@ -2014,7 +2014,7 @@ void Assembler::EmitInstrStringLiteral(Instr* instr, BinStr* literal, BOOL Conve literal->appendInt8(0); pb = literal->ptr(); // convert string to Unicode - L = UnicodeString ? MultiByteToWideChar(g_uCodePage,0,(char*)pb,-1,UnicodeString,DataLen+1) : 0; + L = UnicodeString ? (DWORD)minipal_convert_utf8_to_utf16((char*)pb,strlen((char*)pb)+1,(CHAR16_T*)UnicodeString,DataLen+1,0) : 0; if(L == 0) { const char* sz=NULL; @@ -2412,7 +2412,7 @@ void Assembler::SetPdbFileName(_In_ __nullterminated char* szName) if (*szName) { strcpy_s(m_szPdbFileName, MAX_FILENAME_LENGTH * 3 + 1, szName); - MultiByteToWideChar(g_uCodePage, 0, szName, -1, m_wzPdbFileName, MAX_FILENAME_LENGTH); + minipal_convert_utf8_to_utf16(szName, strlen(szName) + 1, (CHAR16_T*)m_wzPdbFileName, MAX_FILENAME_LENGTH, 0); } } } diff --git a/src/coreclr/ilasm/class.hpp b/src/coreclr/ilasm/class.hpp index cb2c357ad56a6f..10549171e70c1b 100644 --- a/src/coreclr/ilasm/class.hpp +++ b/src/coreclr/ilasm/class.hpp @@ -96,7 +96,7 @@ class Class if(sz) { wzUniBuf[0] = 0; - MultiByteToWideChar(g_uCodePage,0,sz,-1,wzUniBuf,dwUniBuf); + minipal_convert_utf8_to_utf16(sz,strlen(sz)+1,(CHAR16_T*)wzUniBuf,dwUniBuf,0); return FindTyPar(wzUniBuf); } else return -1; diff --git a/src/coreclr/ilasm/grammar_after.cpp b/src/coreclr/ilasm/grammar_after.cpp index f624555da12e83..76f7f633b2b3f3 100644 --- a/src/coreclr/ilasm/grammar_after.cpp +++ b/src/coreclr/ilasm/grammar_after.cpp @@ -120,7 +120,7 @@ char* NewStrFromTokenW(_In_reads_(tokLen) void* curTok, size_t tokLen) char *nb = new char[(tokLen<<1) + 2]; if(nb != NULL) { - tokLen = WideCharToMultiByte(CP_UTF8,0,(LPCWSTR)wcurTok,(int)(tokLen >> 1),nb,(int)(tokLen<<1) + 2,NULL,NULL); + tokLen = minipal_convert_utf16_to_utf8((const CHAR16_T*)wcurTok,tokLen >> 1,nb,(tokLen<<1) + 2,0); nb[tokLen] = 0; } return nb; @@ -143,7 +143,7 @@ char* NewStaticStrFromTokenW(_In_reads_(tokLen) char* curTok, size_t tokLen, _Ou // CodeQL [SM02986] Cast to WCHAR is safe because we bail if curTok is not properly aligned WCHAR* wcurTok = (WCHAR*)curTok; if(tokLen >= bufSize/2) return NULL; - tokLen = WideCharToMultiByte(CP_UTF8,0,(LPCWSTR)wcurTok,(int)(tokLen >> 1),staticBuf,(int)bufSize,NULL,NULL); + tokLen = minipal_convert_utf16_to_utf8((const CHAR16_T*)wcurTok,tokLen >> 1,staticBuf,bufSize,0); staticBuf[tokLen] = 0; return staticBuf; } @@ -990,7 +990,7 @@ int yylex() { if((wzFile = new WCHAR[tokLen+1]) != NULL) { - tokLen = MultiByteToWideChar(g_uCodePage,0,curTok,(int)tokLen,wzFile,(int)tokLen+1); + tokLen = minipal_convert_utf8_to_utf16(curTok,tokLen,(CHAR16_T*)wzFile,tokLen+1,0); wzFile[tokLen] = 0; } } @@ -1793,15 +1793,6 @@ BinStr* AsmParse::MakeTypeClass(CorElementType kind, mdToken tk) /**************************************************************************/ void PrintANSILine(FILE* pF, _In_ __nullterminated char* sz) { - WCHAR *wz = &wzUniBuf[0]; - if(g_uCodePage != CP_ACP) - { - memset(wz,0,dwUniBuf); // dwUniBuf/2 WCHARs = dwUniBuf bytes - MultiByteToWideChar(g_uCodePage,0,sz,-1,wz,(dwUniBuf >> 1)-1); - - memset(sz,0,dwUniBuf); - WideCharToMultiByte(g_uConsoleCP,0,wz,-1,sz,dwUniBuf-1,NULL,NULL); - } fprintf(pF,"%s",sz); } /**************************************************************************/ diff --git a/src/coreclr/ilasm/grammar_before.cpp b/src/coreclr/ilasm/grammar_before.cpp index 04286fa137fb5a..523377e88fba9a 100644 --- a/src/coreclr/ilasm/grammar_before.cpp +++ b/src/coreclr/ilasm/grammar_before.cpp @@ -67,8 +67,6 @@ BOOL SkipToken = FALSE; BOOL neg = FALSE; BOOL newclass = FALSE; -extern unsigned int g_uConsoleCP; - struct VarName { char* name; diff --git a/src/coreclr/ilasm/main.cpp b/src/coreclr/ilasm/main.cpp index 58e0ee7573aa69..e69d55ea4b2378 100644 --- a/src/coreclr/ilasm/main.cpp +++ b/src/coreclr/ilasm/main.cpp @@ -52,7 +52,6 @@ class NarrowForNumberParsing final static DWORD g_dwSubsystem=(DWORD)-1,g_dwComImageFlags=(DWORD)-1,g_dwFileAlignment=0,g_dwTestRepeat=0; static ULONGLONG g_stBaseAddress=0; static size_t g_stSizeOfStackReserve=0; -extern unsigned int g_uConsoleCP; void MakeTestFile(_In_ __nullterminated char* szFileName) { @@ -94,7 +93,7 @@ void MakeProperSourceFileName(_In_ __nullterminated WCHAR* wzOrigName, } } while(j); - WideCharToMultiByte(uCodePage,0,wzProperName,-1,szProperName,MAX_FILENAME_LENGTH*3-1,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wzProperName,u16_strlen(wzProperName)+1,szProperName,MAX_FILENAME_LENGTH*3-1,0); } char* FullFileName(_In_ __nullterminated WCHAR* wzFileName, unsigned uCodePage) @@ -103,7 +102,7 @@ char* FullFileName(_In_ __nullterminated WCHAR* wzFileName, unsigned uCodePage) WCHAR* pwz; GetFullPathName(wzFileName,MAX_FILENAME_LENGTH,wzFullPath,&pwz); char szFullPath[MAX_FILENAME_LENGTH*3]; - WideCharToMultiByte(uCodePage,0,wzFullPath,-1,szFullPath,MAX_FILENAME_LENGTH*3-1,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wzFullPath,u16_strlen(wzFullPath)+1,szFullPath,MAX_FILENAME_LENGTH*3-1,0); char* sz = new char[strlen(szFullPath)+1]; if(sz) strcpy_s(sz,strlen(szFullPath)+1,szFullPath); return sz; @@ -140,7 +139,6 @@ extern "C" int _cdecl wmain(int argc, _In_ WCHAR **argv) memset(&cw,0,sizeof(Clockwork)); cw.cBegin = minipal_lowres_ticks(); - g_uConsoleCP = GetConsoleOutputCP(); memset(wzOutputFilename,0,sizeof(wzOutputFilename)); memset(wzPdbFilename, 0, sizeof(wzPdbFilename)); @@ -223,7 +221,8 @@ extern "C" int _cdecl wmain(int argc, _In_ WCHAR **argv) #endif { char szOpt[3 + 1] = { 0 }; - WideCharToMultiByte(uCodePage, 0, &argv[i][1], 3, szOpt, sizeof(szOpt), NULL, NULL); + size_t cchOpt = u16_strlen(&argv[i][1]); + minipal_convert_utf16_to_utf8((const CHAR16_T*)&argv[i][1], cchOpt < 3 ? cchOpt : 3, szOpt, sizeof(szOpt), 0); if (!_stricmp(szOpt, "NOA")) { pAsm->m_fAutoInheritFromObject = FALSE; @@ -319,7 +318,7 @@ extern "C" int _cdecl wmain(int argc, _In_ WCHAR **argv) // We could change it to be longer, but that would affect the existing usability (ARM64 was // added much later). Thus, just distinguish the two here. char szOpt2[5 + 1] = { 0 }; - WideCharToMultiByte(uCodePage, 0, &argv[i][1], 5, szOpt2, sizeof(szOpt2), NULL, NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)&argv[i][1], cchOpt < 5 ? cchOpt : 5, szOpt2, sizeof(szOpt2), 0); if (!_stricmp(szOpt2, "ARM")) { pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_MACHINE_MASK; @@ -687,7 +686,7 @@ extern "C" int _cdecl wmain(int argc, _In_ WCHAR **argv) { char szOutputFilename[MAX_FILENAME_LENGTH*3]; memset(szOutputFilename,0,sizeof(szOutputFilename)); - WideCharToMultiByte(uCodePage,0,wzOutputFilename,-1,szOutputFilename,MAX_FILENAME_LENGTH*3-1,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wzOutputFilename,u16_strlen(wzOutputFilename)+1,szOutputFilename,MAX_FILENAME_LENGTH*3-1,0); pParser->msg(" --> '%s'\n", szOutputFilename); } } @@ -889,13 +888,14 @@ int main(int argc, char* str[]) WCHAR **argv = new WCHAR*[argc]; for (int i = 0; i < argc; i++) { - int length = MultiByteToWideChar(CP_ACP, 0, str[i], -1, NULL, 0); + size_t cch = strlen(str[i]) + 1; + size_t length = minipal_get_length_utf8_to_utf16(str[i], cch, 0); ASSERTE_ALL_BUILDS(length != 0); LPWSTR result = new (nothrow) WCHAR[length]; ASSERTE_ALL_BUILDS(result != NULL); - length = MultiByteToWideChar(CP_ACP, 0, str[i], -1, result, length); + length = minipal_convert_utf8_to_utf16(str[i], cch, (CHAR16_T*)result, length, 0); ASSERTE_ALL_BUILDS (length != 0); argv[i] = result; diff --git a/src/coreclr/ilasm/method.hpp b/src/coreclr/ilasm/method.hpp index dfd22c1f79691f..e82b3d6ea6f139 100644 --- a/src/coreclr/ilasm/method.hpp +++ b/src/coreclr/ilasm/method.hpp @@ -373,7 +373,7 @@ class Method if(sz) { wzUniBuf[0] = 0; - MultiByteToWideChar(g_uCodePage,0,sz,-1,wzUniBuf,dwUniBuf); + minipal_convert_utf8_to_utf16(sz,strlen(sz)+1,(CHAR16_T*)wzUniBuf,dwUniBuf,0); return FindTyPar(wzUniBuf); } else return -1; diff --git a/src/coreclr/ilasm/typar.hpp b/src/coreclr/ilasm/typar.hpp index 5b6f94cc3adab0..de94e9f641783b 100644 --- a/src/coreclr/ilasm/typar.hpp +++ b/src/coreclr/ilasm/typar.hpp @@ -33,7 +33,7 @@ class TyParDescr if(pwzName) { memset(pwzName,0,sizeof(WCHAR)*cTemp); - MultiByteToWideChar(g_uCodePage,0,name,-1,pwzName,cTemp); + minipal_convert_utf8_to_utf16(name,strlen(name)+1,(CHAR16_T*)pwzName,cTemp,0); } m_dwAttrs = attrs; }; @@ -119,7 +119,7 @@ class TyParList { WCHAR* wzDllName = new WCHAR [cTemp]; // Convert name to UNICODE memset(wzDllName,0,sizeof(WCHAR)*cTemp); - MultiByteToWideChar(g_uCodePage,0,tp->name,-1,wzDllName,cTemp); + minipal_convert_utf8_to_utf16(tp->name,strlen(tp->name)+1,(CHAR16_T*)wzDllName,cTemp,0); nam[i] = (LPCWSTR)wzDllName; b[i] = tp->bound; if (attr) diff --git a/src/coreclr/ilasm/writer.cpp b/src/coreclr/ilasm/writer.cpp index 1fe27fb53e6cd9..2a00c70b8dce51 100644 --- a/src/coreclr/ilasm/writer.cpp +++ b/src/coreclr/ilasm/writer.cpp @@ -7,6 +7,7 @@ #include "ceefilegenwriter.h" #include "sha256.h" +#include #ifndef _MSC_VER //cloned definition from ntimage.h that is removed for non MSVC builds @@ -498,7 +499,7 @@ HRESULT Assembler::CreateExportDirectory() Ldllname = (unsigned)u16_strlen(m_wzOutputFileName)*3+3; NewArrayHolder szOutputFileName(new char[Ldllname]); memset(szOutputFileName,0,u16_strlen(m_wzOutputFileName)*3+3); - WideCharToMultiByte(CP_ACP,0,m_wzOutputFileName,-1,szOutputFileName,Ldllname,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)m_wzOutputFileName,u16_strlen(m_wzOutputFileName)+1,szOutputFileName,Ldllname,0); pszDllName = strrchr(szOutputFileName,DIRECTORY_SEPARATOR_CHAR_A); #ifdef TARGET_WINDOWS if(pszDllName == NULL) pszDllName = strrchr(szOutputFileName,':'); @@ -874,7 +875,7 @@ HRESULT Assembler::ResolveLocalMemberRefs() } if(tkMemberDef && ((*pMRD_pSig & IMAGE_CEE_CS_CALLCONV_MASK)==IMAGE_CEE_CS_CALLCONV_VARARG)) { - MultiByteToWideChar(g_uCodePage,0,pMRD_szName,-1,wzUniBuf,dwUniBuf); + minipal_convert_utf8_to_utf16(pMRD_szName,strlen(pMRD_szName)+1,(CHAR16_T*)wzUniBuf,dwUniBuf,0); if(IsMdPrivateScope(pListMD->m_Attr)) { @@ -917,7 +918,7 @@ HRESULT Assembler::ResolveLocalMemberRefs() if(RidFromToken(tkRef)) { - MultiByteToWideChar(g_uCodePage,0,pMRD_szName,-1,wzUniBuf,dwUniBuf); + minipal_convert_utf8_to_utf16(pMRD_szName,strlen(pMRD_szName)+1,(CHAR16_T*)wzUniBuf,dwUniBuf,0); m_pEmitter->DefineMemberRef(tkRef, wzUniBuf, pMRD_pSig, pMRD_dwCSig, &tkMemberDef); @@ -1205,7 +1206,7 @@ HRESULT Assembler::CreatePEFile(_In_ __nullterminated WCHAR *pwzOutputFilename) wzScopeName=&wzUniBuf[0]; if(m_szScopeName[0]) // default: scope name = output file name { - MultiByteToWideChar(g_uCodePage,0,m_szScopeName,-1,wzScopeName,MAX_SCOPE_LENGTH); + minipal_convert_utf8_to_utf16(m_szScopeName,strlen(m_szScopeName)+1,(CHAR16_T*)wzScopeName,MAX_SCOPE_LENGTH,0); } else { @@ -1705,12 +1706,12 @@ HRESULT Assembler::CreatePEFile(_In_ __nullterminated WCHAR *pwzOutputFilename) { m_pManifest->m_fMResNew[i] = FALSE; memset(sz,0,2048); - WideCharToMultiByte(CP_ACP,0,m_pManifest->m_wzMResName[i],-1,sz,2047,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)m_pManifest->m_wzMResName[i],u16_strlen(m_pManifest->m_wzMResName[i])+1,sz,2047,0); L = m_pManifest->m_dwMResSize[i]; sizeread = 0; memcpy(ptr,&L,sizeof(DWORD)); ptr += sizeof(DWORD); - if(fopen_s(&pFile,sz,"rb") == 0) + if(fopen_lp(&pFile,m_pManifest->m_wzMResName[i],W("rb")) == 0) { sizeread = fread((void *)ptr,1,L,pFile); fclose(pFile); diff --git a/src/coreclr/ildasm/dasm.cpp b/src/coreclr/ildasm/dasm.cpp index 617a9b98d517f3..2f43dcb7064602 100644 --- a/src/coreclr/ildasm/dasm.cpp +++ b/src/coreclr/ildasm/dasm.cpp @@ -259,7 +259,7 @@ char* RstrA(unsigned n, unsigned codepage) WCHAR* wz = RstrW(n); // Unicode -> UTF-8 memset(buff,0,sizeof(buff)); - if(!WideCharToMultiByte(codepage,0,(LPCWSTR)wz,-1,buff,sizeof(buff),NULL,NULL)) + if(!minipal_convert_utf16_to_utf8((const CHAR16_T*)wz,u16_strlen(wz)+1,buff,sizeof(buff),0)) buff[0] = 0; return buff; } @@ -3088,7 +3088,7 @@ char *DumpGenericPars(_Inout_updates_(SZSTRING_SIZE) char* szString, mdToken tok if (chName) { char* sz = (char*)(&wzUniBuf[UNIBUF_SIZE/2]); - WideCharToMultiByte(CP_UTF8,0,wzArgName,-1,sz,UNIBUF_SIZE,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wzArgName,u16_strlen(wzArgName)+1,sz,UNIBUF_SIZE,0); szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),"%s",ProperName(sz)); } CHECK_REMAINING_SIZE; @@ -3156,7 +3156,7 @@ void DumpGenericParsCA(mdToken tok, void* GUICookie/*=NULL*/) //if(u16_strlen(wzArgName) >= MAX_CLASSNAME_LENGTH) // wzArgName[MAX_CLASSNAME_LENGTH-1] = 0; char* sz = (char*)(&wzUniBuf[UNIBUF_SIZE/2]); - WideCharToMultiByte(CP_UTF8,0,wzArgName,-1,sz,UNIBUF_SIZE,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wzArgName,u16_strlen(wzArgName)+1,sz,UNIBUF_SIZE,0); szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),"%s ",ProperName(sz)); } else @@ -3224,7 +3224,7 @@ void DumpGenericParsCA(mdToken tok, void* GUICookie/*=NULL*/) if (chName > 0) { char* sz = (char*)(&wzUniBuf[UNIBUF_SIZE / 2]); - WideCharToMultiByte(CP_UTF8, 0, wzArgName, -1, sz, UNIBUF_SIZE, NULL, NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wzArgName, u16_strlen(wzArgName) + 1, sz, UNIBUF_SIZE, 0); szptr += sprintf_s(szptr, SZSTRING_REMAINING_SIZE(szptr), " %s", ProperName(sz)); } else @@ -6775,7 +6775,7 @@ void DumpMetaInfo(_In_ __nullterminated const WCHAR* pwzFileName, _In_opt_z_ con int nLength = (int) strlen(pszObjFileName)+1; pwzObjFileName = new WCHAR[nLength]; memset(pwzObjFileName,0,sizeof(WCHAR)*nLength); - MultiByteToWideChar(CP_UTF8,0,pszObjFileName,-1,pwzObjFileName,nLength); + minipal_convert_utf8_to_utf16(pszObjFileName,strlen(pszObjFileName)+1,(CHAR16_T*)pwzObjFileName,nLength,0); } DisplayFile((WCHAR*)pwzFileName, true, g_ulMetaInfoFilter, pwzObjFileName, DumpMI); g_pDisp->Release(); @@ -7214,9 +7214,9 @@ BOOL DumpFile() } memset(wzInputFileName,0,sizeof(WCHAR)*MAX_FILENAME_LENGTH); - MultiByteToWideChar(CP_UTF8,0,pszFilename,-1,wzInputFileName,MAX_FILENAME_LENGTH); + minipal_convert_utf8_to_utf16(pszFilename,strlen(pszFilename)+1,(CHAR16_T*)wzInputFileName,MAX_FILENAME_LENGTH,0); memset(szFilenameANSI,0,MAX_FILENAME_LENGTH*3); - WideCharToMultiByte(g_uConsoleCP,0,wzInputFileName,-1,szFilenameANSI,MAX_FILENAME_LENGTH*3,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wzInputFileName,u16_strlen(wzInputFileName)+1,szFilenameANSI,MAX_FILENAME_LENGTH*3,0); fSuccess = g_pPELoader->open(wzInputFileName); if (fSuccess == FALSE) @@ -7566,7 +7566,7 @@ BOOL DumpFile() { WCHAR wzResFileName[2048], *pwc; memset(wzResFileName,0,sizeof(wzResFileName)); - MultiByteToWideChar(CP_UTF8,0,g_szOutputFile,-1,wzResFileName,2048); + minipal_convert_utf8_to_utf16(g_szOutputFile,strlen(g_szOutputFile)+1,(CHAR16_T*)wzResFileName,2048,0); pwc = (WCHAR*)u16_strrchr(wzResFileName,L'.'); if(pwc == NULL) pwc = &wzResFileName[u16_strlen(wzResFileName)]; wcscpy_s(pwc, 2048 - (pwc - wzResFileName), L".res"); diff --git a/src/coreclr/ildasm/dis.cpp b/src/coreclr/ildasm/dis.cpp index 9afb147a4847f8..125083501df833 100644 --- a/src/coreclr/ildasm/dis.cpp +++ b/src/coreclr/ildasm/dis.cpp @@ -93,7 +93,7 @@ OPCODE DecodeOpcode(const BYTE *pCode, DWORD *pdwLen) WCHAR* UtfToUnicode(_In_ __nullterminated const char* sz) { WCHAR* wz = wzUniBuf; - if (MultiByteToWideChar(CP_UTF8,0,sz,-1,wz,UNIBUF_SIZE/2) == 0) + if (minipal_convert_utf8_to_utf16(sz,strlen(sz)+1,(CHAR16_T*)wz,UNIBUF_SIZE/2,0) == 0) { wz[UNIBUF_SIZE/2 - 1] = 0; } @@ -102,7 +102,7 @@ WCHAR* UtfToUnicode(_In_ __nullterminated const char* sz) char* UnicodeToAnsi(_In_ __nullterminated const WCHAR* wz) { char* sz = (char*)(&wzUniBuf[UNIBUF_SIZE/2]); - if (WideCharToMultiByte(g_uConsoleCP,0,wz,-1,sz,UNIBUF_SIZE,NULL,NULL) == 0) + if (minipal_convert_utf16_to_utf8((const CHAR16_T*)wz,u16_strlen(wz)+1,sz,UNIBUF_SIZE,0) == 0) { sz[UNIBUF_SIZE - 1] = 0; } @@ -111,7 +111,7 @@ char* UnicodeToAnsi(_In_ __nullterminated const WCHAR* wz) WCHAR* AnsiToUnicode(_In_ __nullterminated const char* sz) { WCHAR* wz = wzUniBuf; - if (MultiByteToWideChar(g_uConsoleCP,0,sz,-1,wz,UNIBUF_SIZE/2) == 0) + if (minipal_convert_utf8_to_utf16(sz,strlen(sz)+1,(CHAR16_T*)wz,UNIBUF_SIZE/2,0) == 0) { wz[UNIBUF_SIZE/2 - 1] = 0; } @@ -120,7 +120,7 @@ WCHAR* AnsiToUnicode(_In_ __nullterminated const char* sz) char* UnicodeToUtf(_In_ __nullterminated const WCHAR* wz) { char* sz = (char*)(&wzUniBuf[UNIBUF_SIZE/2]); - if (WideCharToMultiByte(CP_UTF8,0,wz,-1,sz,UNIBUF_SIZE,NULL,NULL) == 0) + if (minipal_convert_utf16_to_utf8((const CHAR16_T*)wz,u16_strlen(wz)+1,sz,UNIBUF_SIZE,0) == 0) { sz[UNIBUF_SIZE - 1] = 0; } @@ -737,7 +737,7 @@ char* DumpUnicodeString(void* GUICookie, szStr = new char[cbString*3 + 5]; memset(szStr,0,cbString*3 + 5); - WideCharToMultiByte(CP_UTF8,0,pszString,cbString,&szStr[0],cbString*3,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)pszString,cbString,&szStr[0],cbString*3,0); L = (unsigned)strlen(szStr); szStr[L] = 0; @@ -1079,7 +1079,7 @@ BOOL Disassemble(IMDInternalImport *pImport, BYTE *ILHeader, void *GUICookie, md { wcscpy_s(wzWasFileName,2048,wzFileName); memset(szFileName,0,2048); - WideCharToMultiByte(CP_UTF8,0,wzFileName,-1,szFileName,2048,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wzFileName,u16_strlen(wzFileName)+1,szFileName,2048,0); if(fShowSource) { if(pFile) fclose(pFile); diff --git a/src/coreclr/ildasm/dman.cpp b/src/coreclr/ildasm/dman.cpp index 240f4a42e6f2aa..7ca18ae832a2a8 100644 --- a/src/coreclr/ildasm/dman.cpp +++ b/src/coreclr/ildasm/dman.cpp @@ -74,7 +74,7 @@ void DumpFiles(void* GUICookie) int L = ulNameLen*3+3; char* sz = new char[L]; memset(sz,0,L); - WideCharToMultiByte(CP_UTF8,0,rFile[ix].name,-1,sz,L,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)rFile[ix].name,u16_strlen(rFile[ix].name)+1,sz,L,0); strcpy_s(szptr,SZSTRING_REMAINING_SIZE(szptr), ANCHORPT(ProperName(sz),rFileTok[ix])); VDELETE(sz); } @@ -126,7 +126,7 @@ void DumpScope(void* GUICookie) UINT32 L = (UINT32)u16_strlen(scopeName)*3+3; char* sz = new char[L]; memset(sz,0,L); - WideCharToMultiByte(CP_UTF8,0,scopeName,-1,sz,L,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)scopeName,u16_strlen(scopeName)+1,sz,L,0); sprintf_s(szString,SZSTRING_SIZE,"%s%s %s",g_szAsmCodeIndent,KEYWORD(".module"),ProperName(sz)); VDELETE(sz); } @@ -232,7 +232,7 @@ void DumpAssembly(void* GUICookie, BOOL fFullDump) { char* sz = new char[3*ulNameLen+3]; memset(sz,0,3*ulNameLen+3); - WideCharToMultiByte(CP_UTF8,0,wzName,-1,sz,3*ulNameLen+3,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wzName,u16_strlen(wzName)+1,sz,3*ulNameLen+3,0); strcat_s(szString,SZSTRING_SIZE,ANCHORPT(ProperName(sz),tkAsm)); VDELETE(sz); } @@ -354,7 +354,7 @@ void DumpAssemblyRefs(void* GUICookie) { char* sz = new char[3*ulNameLen+32]; memset(sz,0,3*ulNameLen+3); - WideCharToMultiByte(CP_UTF8,0,rAsmRef[ix].name,-1,sz,3*ulNameLen+3,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)rAsmRef[ix].name,u16_strlen(rAsmRef[ix].name)+1,sz,3*ulNameLen+3,0); // check for name duplication and introduce alias if needed for(ixx = 0; ixx < ix; ixx++) { @@ -424,7 +424,7 @@ void DumpComTypeFQN( UINT32 L = (UINT32)u16_strlen(pCTD->wzName)*3+3; char* sz = new char[L]; memset(sz,0,L); - WideCharToMultiByte(CP_UTF8,0,pCTD->wzName,-1,sz,L,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)pCTD->wzName,u16_strlen(pCTD->wzName)+1,sz,L,0); strcat_s(szName, SZSTRING_SIZE, JUMPPT(ProperName(sz), pCTD->tkComTypeTok)); VDELETE(sz); } @@ -447,7 +447,7 @@ void DumpImplementation(mdToken tkImplementation, UINT32 L = (UINT32)u16_strlen(rFile[i].name)*3+3; char* sz = new char[L]; memset(sz,0,L); - WideCharToMultiByte(CP_UTF8,0,rFile[i].name,-1,sz,L,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)rFile[i].name,u16_strlen(rFile[i].name)+1,sz,L,0); sprintf_s(szString,SZSTRING_SIZE,"%s%s %s",g_szAsmCodeIndent,KEYWORD(".file"), JUMPPT(ProperName(sz),tkImplementation)); VDELETE(sz); @@ -467,7 +467,7 @@ void DumpImplementation(mdToken tkImplementation, UINT32 L = (UINT32)u16_strlen(rAsmRef[i].name)*3+3; char* sz = new char[L]; memset(sz,0,L); - WideCharToMultiByte(CP_UTF8,0,rAsmRef[i].name,-1,sz,L,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)rAsmRef[i].name,u16_strlen(rAsmRef[i].name)+1,sz,L,0); sprintf_s(szString,SZSTRING_SIZE,"%s%s %s",g_szAsmCodeIndent,KEYWORD(".assembly extern"), JUMPPT(ProperName(sz),tkImplementation)); VDELETE(sz); @@ -513,7 +513,7 @@ void DumpComType(LocalComTypeDescr* pCTD, UINT32 L = (UINT32)u16_strlen(pCTD->wzName)*3+3; char* sz = new char[L]; memset(sz,0,L); - WideCharToMultiByte(CP_UTF8,0,pCTD->wzName,-1,sz,L,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)pCTD->wzName,u16_strlen(pCTD->wzName)+1,sz,L,0); strcpy_s(pc,SZSTRING_REMAINING_SIZE(pc),ANCHORPT(ProperName(sz),pCTD->tkComTypeTok)); VDELETE(sz); } @@ -778,7 +778,7 @@ void DumpManifestResources(void* GUICookie) static WCHAR wzFileName[2048]; - MultiByteToWideChar(CP_UTF8,0,g_szOutputFile,-1,wzFileName,2048); + minipal_convert_utf8_to_utf16(g_szOutputFile,strlen(g_szOutputFile)+1,(CHAR16_T*)wzFileName,2048,0); wzName = (WCHAR*)u16_strrchr(wzFileName,DIRECTORY_SEPARATOR_CHAR_W); #ifdef HOST_WINDOWS if(wzName == NULL) wzName = (WCHAR*)u16_strrchr(wzFileName,':'); @@ -835,7 +835,7 @@ void DumpManifestResources(void* GUICookie) char* pc = szString + strlen(szString); wzName[ulNameLen]=0; - WideCharToMultiByte(CP_UTF8,0,wzName,-1,sz,sizeof(sz),NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wzName,u16_strlen(wzName)+1,sz,sizeof(sz),0); strcpy_s(pc,SZSTRING_REMAINING_SIZE(pc),ProperName(sz)); // get rid of invalid characters and reserved names @@ -890,7 +890,7 @@ void DumpManifestResources(void* GUICookie) if(fAlias) { // update sz with the aliased name and print the 'as' keyword - if (WideCharToMultiByte(CP_UTF8, 0, wzName, -1, sz, sizeof(sz), NULL, NULL) == 0) + if (minipal_convert_utf16_to_utf8((const CHAR16_T*)wzName, u16_strlen(wzName) + 1, sz, sizeof(sz), 0) == 0) { sz[sizeof(sz) - 1] = 0; } diff --git a/src/coreclr/ildasm/windasm.cpp b/src/coreclr/ildasm/windasm.cpp index 4bf36bb6c08962..1c89fc32b1074f 100644 --- a/src/coreclr/ildasm/windasm.cpp +++ b/src/coreclr/ildasm/windasm.cpp @@ -143,7 +143,7 @@ void GetInputFileFullPath() DWORD len = (DWORD) strlen(g_szInputFile) + 16; WCHAR* wzArg = new WCHAR[len]; memset(wzArg, 0, len * sizeof(WCHAR)); - MultiByteToWideChar(g_uConsoleCP, 0, g_szInputFile, -1, wzArg, len); + minipal_convert_utf8_to_utf16(g_szInputFile, strlen(g_szInputFile) + 1, (CHAR16_T*)wzArg, len, 0); // Get the full path len = GetFullPathName(wzArg, MAX_PATH, g_wszFullInputFile, NULL); @@ -427,7 +427,7 @@ int ParseCmdLineW(int argc, _In_ __nullterminated wchar_t* argv[], _Out_ char** for(int i=1; i < argc; i++) { memset(szArg,0,2048); - WideCharToMultiByte(CP_UTF8,0,argv[i],-1,szArg,2048,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)argv[i],u16_strlen(argv[i])+1,szArg,2048,0); if((ret = ProcessOneArg(szArg,ppszObjFileName)) != 0) break; } VDELETE(szArg); @@ -508,7 +508,7 @@ int main(int argc, char* argv[]) } if(hConsoleOut != INVALID_HANDLE_VALUE) //First pass: console { - g_uConsoleCP = GetConsoleOutputCP(); + g_uConsoleCP = CP_UTF8; if(iCommandLineParsed) { diff --git a/src/coreclr/inc/mdfileformat.h b/src/coreclr/inc/mdfileformat.h index 85dbb6c1be3104..13e24f21a7a110 100644 --- a/src/coreclr/inc/mdfileformat.h +++ b/src/coreclr/inc/mdfileformat.h @@ -198,13 +198,13 @@ struct STORAGESTREAM } inline LPCWSTR GetName(__inout_ecount (iMaxSize) LPWSTR szName, int iMaxSize) { - VERIFY(::MultiByteToWideChar(CP_ACP, 0, rcName, -1, szName, iMaxSize)); + VERIFY(minipal_convert_utf8_to_utf16(rcName, strlen(rcName) + 1, (CHAR16_T*)szName, iMaxSize, 0)); return (szName); } inline void SetName(LPCWSTR szName) { - int size; - size = WideCharToMultiByte(CP_ACP, 0, szName, -1, rcName, MAXSTREAMNAME, 0, 0); + size_t size; + size = minipal_convert_utf16_to_utf8((const CHAR16_T*)szName, u16_strlen(szName) + 1, rcName, MAXSTREAMNAME, 0); _ASSERTE(size > 0); } diff --git a/src/coreclr/inc/utilcode.h b/src/coreclr/inc/utilcode.h index fa397c30c9c4fa..e43efebdb15d17 100644 --- a/src/coreclr/inc/utilcode.h +++ b/src/coreclr/inc/utilcode.h @@ -39,6 +39,7 @@ using std::nothrow; #include #include #include +#include #include #include "clrnt.h" @@ -206,28 +207,18 @@ typedef LPSTR LPUTF8; // ptrname will be deleted when it goes out of scope. #define MAKE_UTF8PTR_FROMWIDE_NOTHROW(ptrname, widestr) \ CQuickBytes __qb##ptrname; \ - int __l##ptrname = (int)u16_strlen(widestr); \ + size_t __lsrc##ptrname = u16_strlen(widestr) + 1; \ + size_t __l##ptrname = 0; \ LPUTF8 ptrname = NULL; \ - if (__l##ptrname <= MAKE_MAX_LENGTH) { \ - __l##ptrname = (int)((__l##ptrname + 1) * 2 * sizeof(char)); \ + if (__lsrc##ptrname <= MAKE_MAX_LENGTH) { \ + __l##ptrname = __lsrc##ptrname * 2; \ ptrname = (LPUTF8) __qb##ptrname.AllocNoThrow(__l##ptrname); \ } \ if (ptrname) { \ - INT32 __lresult##ptrname=WideCharToMultiByte(CP_UTF8, 0, widestr, -1, ptrname, __l##ptrname-1, NULL, NULL); \ - DWORD __dwCaptureLastError##ptrname = ::GetLastError(); \ - if ((__lresult##ptrname==0) && (((LPCWSTR)widestr)[0] != W('\0'))) { \ - if (__dwCaptureLastError##ptrname==ERROR_INSUFFICIENT_BUFFER) { \ - INT32 __lsize##ptrname=WideCharToMultiByte(CP_UTF8, 0, widestr, -1, NULL, 0, NULL, NULL); \ - ptrname = (LPSTR) __qb##ptrname .AllocNoThrow(__lsize##ptrname); \ - if (ptrname) { \ - if (WideCharToMultiByte(CP_UTF8, 0, widestr, -1, ptrname, __lsize##ptrname, NULL, NULL) != 0) { \ - ptrname[__l##ptrname] = 0; \ - } else { \ - ptrname = NULL; \ - } \ - } \ - } \ - else { \ + if (minipal_convert_utf16_to_utf8((const CHAR16_T*)(widestr), __lsrc##ptrname, ptrname, __l##ptrname, 0) == 0) { \ + __l##ptrname = minipal_get_length_utf16_to_utf8((const CHAR16_T*)(widestr), __lsrc##ptrname, 0); \ + ptrname = (LPUTF8) __qb##ptrname.AllocNoThrow(__l##ptrname); \ + if (ptrname && minipal_convert_utf16_to_utf8((const CHAR16_T*)(widestr), __lsrc##ptrname, ptrname, __l##ptrname, 0) == 0) { \ ptrname = NULL; \ } \ } \ @@ -237,21 +228,23 @@ typedef LPSTR LPUTF8; #define MAKE_WIDEPTR_FROMUTF8N_NOTHROW(ptrname, utf8str, n8chrs) \ CQuickBytes __qb##ptrname; \ - int __l##ptrname; \ + size_t __n##ptrname = (size_t)(n8chrs); \ LPWSTR ptrname = NULL; \ - __l##ptrname = MultiByteToWideChar(CP_UTF8, 0, utf8str, n8chrs, 0, 0); \ - if (__l##ptrname <= MAKE_MAX_LENGTH) { \ - ptrname = (LPWSTR) __qb##ptrname.AllocNoThrow((__l##ptrname+1)*sizeof(WCHAR)); \ - if (ptrname) { \ - if (MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8str, n8chrs, ptrname, __l##ptrname) != 0) { \ - ptrname[__l##ptrname] = 0; \ - } else { \ - ptrname = NULL; \ + if (__n##ptrname != 0) { \ + size_t __l##ptrname = minipal_get_length_utf8_to_utf16(utf8str, __n##ptrname, 0); \ + if (__l##ptrname <= MAKE_MAX_LENGTH) { \ + ptrname = (LPWSTR) __qb##ptrname.AllocNoThrow((__l##ptrname+1)*sizeof(WCHAR)); \ + if (ptrname) { \ + if (minipal_convert_utf8_to_utf16(utf8str, __n##ptrname, (CHAR16_T*)ptrname, __l##ptrname, MINIPAL_MB_NO_REPLACE_INVALID_CHARS) != 0) { \ + ptrname[__l##ptrname] = 0; \ + } else { \ + ptrname = NULL; \ + } \ } \ } \ } -#define MAKE_WIDEPTR_FROMUTF8_NOTHROW(ptrname, utf8str) MAKE_WIDEPTR_FROMUTF8N_NOTHROW(ptrname, utf8str, -1) +#define MAKE_WIDEPTR_FROMUTF8_NOTHROW(ptrname, utf8str) MAKE_WIDEPTR_FROMUTF8N_NOTHROW(ptrname, utf8str, (utf8str) != NULL ? strlen(utf8str) + 1 : 0) const SIZE_T MaxSigned32BitDecString = ARRAY_SIZE("-2147483648") - 1; const SIZE_T MaxUnsigned32BitDecString = ARRAY_SIZE("4294967295") - 1; diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index 2ae032145ad851..790d03d9237497 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -24,6 +24,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #include "opcode.h" #include "jitstd/algorithm.h" #include "minipal/time.h" +#include "minipal/utf8.h" /*****************************************************************************/ @@ -3934,13 +3935,10 @@ class Utf16String public: Utf16String(const char* str) { - int strBufferSize = MultiByteToWideChar(CP_UTF8, 0, str, -1, nullptr, 0); - if (strBufferSize == 0) - { - return; - } + size_t strLength = strlen(str) + 1; + size_t strBufferSize = minipal_get_length_utf8_to_utf16(str, strLength, 0); - if (static_cast(strBufferSize) > bufferSize) + if (strBufferSize > bufferSize) { m_pBuffer = new WCHAR[strBufferSize]; } @@ -3949,15 +3947,7 @@ class Utf16String m_pBuffer = m_bufferUnsafe; } - if (MultiByteToWideChar(CP_UTF8, 0, str, -1, m_pBuffer, strBufferSize) == 0) - { - if (m_pBuffer != m_bufferUnsafe) - { - delete[] m_pBuffer; - } - - m_pBuffer = nullptr; - } + minipal_convert_utf8_to_utf16(str, strLength, (CHAR16_T*)m_pBuffer, strBufferSize, 0); } ~Utf16String() diff --git a/src/coreclr/md/compiler/custattr_import.cpp b/src/coreclr/md/compiler/custattr_import.cpp index 57465fb936ce10..edd10f067c2056 100644 --- a/src/coreclr/md/compiler/custattr_import.cpp +++ b/src/coreclr/md/compiler/custattr_import.cpp @@ -34,15 +34,17 @@ STDMETHODIMP RegMeta::GetCustomAttributeByName( // S_OK or error. HRESULT hr; // A result. LPUTF8 szName; // Name in UFT8. + size_t cchName; // Length of the name, including the terminator. int iLen; // A length. CMiniMdRW *pMiniMd = NULL; LOCKREAD(); pMiniMd = &(m_pStgdb->m_MiniMd); - iLen = WideCharToMultiByte(CP_UTF8,0, wzName,-1, NULL,0, 0,0); + cchName = u16_strlen(wzName) + 1; + iLen = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)wzName, cchName, 0); szName = (LPUTF8)_alloca(iLen); - VERIFY(WideCharToMultiByte(CP_UTF8,0, wzName,-1, szName,iLen, 0,0)); + VERIFY(minipal_convert_utf16_to_utf8((const CHAR16_T*)wzName, cchName, szName, iLen, 0)); hr = ImportHelper::GetCustomAttributeByName(pMiniMd, tkObj, szName, ppData, pcbData); diff --git a/src/coreclr/md/compiler/disp.cpp b/src/coreclr/md/compiler/disp.cpp index d1d8ad6e066a96..05f48690810960 100644 --- a/src/coreclr/md/compiler/disp.cpp +++ b/src/coreclr/md/compiler/disp.cpp @@ -629,11 +629,12 @@ Disp::SetOption( } else { - INT32 len = WideCharToMultiByte(CP_UTF8, 0, V_BSTR(pvalue), -1, NULL, 0, NULL, NULL); + size_t cchVersion = u16_strlen(V_BSTR(pvalue)) + 1; + size_t len = minipal_get_length_utf16_to_utf8((const CHAR16_T*)V_BSTR(pvalue), cchVersion, 0); m_OptionValue.m_RuntimeVersion = new (nothrow) char[len]; if (m_OptionValue.m_RuntimeVersion == NULL) IfFailGo(E_INVALIDARG); - WideCharToMultiByte(CP_UTF8, 0, V_BSTR(pvalue), -1, m_OptionValue.m_RuntimeVersion, len, NULL, NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)V_BSTR(pvalue), cchVersion, m_OptionValue.m_RuntimeVersion, len, 0); } } else if (optionid == MetaDataInitialSize) diff --git a/src/coreclr/md/compiler/import.cpp b/src/coreclr/md/compiler/import.cpp index 098223ebef4094..acdee08ea8f1c6 100644 --- a/src/coreclr/md/compiler/import.cpp +++ b/src/coreclr/md/compiler/import.cpp @@ -2988,17 +2988,24 @@ HRESULT RegMeta::GetVersionString( // S_OK or error. // For convenience, get a pointer to the version string. // @todo: get from alternate locations when there is no STOREAGESIGNATURE. pVer = reinterpret_cast(reinterpret_cast(m_pStgdb->m_pvMd)->pVersion); - // Attempt to convert into caller's buffer. - cch = MultiByteToWideChar(CP_UTF8,0, pVer,-1, pwzBuf,cchBufSize); - // Did the string fit? - if (cch == 0) - { // No, didn't fit. Find out space required. - cch = MultiByteToWideChar(CP_UTF8,0, pVer,-1, pwzBuf,0); - // NUL terminate string. - if (cchBufSize > 0) + size_t cchVer = strlen(pVer) + 1; + if (cchBufSize == 0) + { // Only the space required. + cch = (DWORD)minipal_get_length_utf8_to_utf16(pVer, cchVer, 0); + } + else + { + // Attempt to convert into caller's buffer. + cch = (DWORD)minipal_convert_utf8_to_utf16(pVer, cchVer, (CHAR16_T*)pwzBuf, cchBufSize, 0); + // Did the string fit? + if (cch == 0) + { // No, didn't fit. Find out space required. + cch = (DWORD)minipal_get_length_utf8_to_utf16(pVer, cchVer, 0); + // NUL terminate string. pwzBuf[cchBufSize-1] = W('\0'); - // Truncation return code. - hr = CLDB_S_TRUNCATION; + // Truncation return code. + hr = CLDB_S_TRUNCATION; + } } } else diff --git a/src/coreclr/md/enc/metamodelrw.cpp b/src/coreclr/md/enc/metamodelrw.cpp index 443655f5d4eba6..7f3500546a0ee2 100644 --- a/src/coreclr/md/enc/metamodelrw.cpp +++ b/src/coreclr/md/enc/metamodelrw.cpp @@ -3819,6 +3819,7 @@ CMiniMdRW::Impl_GetStringW( ULONG *pcchBuffer) { LPCSTR szString; // Single byte version. + size_t cchString; // Length of the single byte version, including the terminator. int iSize; // Size of resulting string, in wide chars. HRESULT hr = NOERROR; @@ -3833,18 +3834,16 @@ CMiniMdRW::Impl_GetStringW( *pcchBuffer = 0; goto ErrExit; } - if (!(iSize=::MultiByteToWideChar(CP_UTF8, 0, szString, -1, szOut, cchBuffer))) + cchString = strlen(szString) + 1; + if (cchBuffer == 0) + iSize = (int)minipal_get_length_utf8_to_utf16(szString, cchString, 0); + else + iSize = (int)minipal_convert_utf8_to_utf16(szString, cchString, (CHAR16_T*)szOut, cchBuffer, 0); + if (iSize == 0) { - // What was the problem? - DWORD dwNT = GetLastError(); - - // Not truncation? - if (dwNT != ERROR_INSUFFICIENT_BUFFER) - IfFailGo(HRESULT_FROM_NT(dwNT)); - // Truncation error; get the size required. if (pcchBuffer) - *pcchBuffer = ::MultiByteToWideChar(CP_UTF8, 0, szString, -1, NULL, 0); + *pcchBuffer = (ULONG)minipal_get_length_utf8_to_utf16(szString, cchString, 0); if ((szOut != NULL) && (cchBuffer > 0)) { // null-terminate the truncated output string diff --git a/src/coreclr/md/enc/rwutil.cpp b/src/coreclr/md/enc/rwutil.cpp index 27dd972cd056d9..33ac00b8c66aea 100644 --- a/src/coreclr/md/enc/rwutil.cpp +++ b/src/coreclr/md/enc/rwutil.cpp @@ -164,18 +164,10 @@ Unicode2UTF( LPUTF8 szDst, // Buffer for the output UTF8 string. int cbDst) // Size of the buffer for UTF8 string. { - int cchSrc = (int)u16_strlen(wszSrc); - int cchRet; - - cchRet = WideCharToMultiByte( - CP_UTF8, - 0, - wszSrc, - cchSrc + 1, - szDst, - cbDst, - NULL, - NULL); + size_t cchSrc = u16_strlen(wszSrc); + size_t cchRet; + + cchRet = minipal_convert_utf16_to_utf8((const CHAR16_T*)wszSrc, cchSrc + 1, szDst, cbDst, 0); if (cchRet == 0) { diff --git a/src/coreclr/md/enc/stgtiggerstorage.cpp b/src/coreclr/md/enc/stgtiggerstorage.cpp index 22551616b43508..8774d055530845 100644 --- a/src/coreclr/md/enc/stgtiggerstorage.cpp +++ b/src/coreclr/md/enc/stgtiggerstorage.cpp @@ -361,7 +361,7 @@ TiggerStorage::GetStreamSaveSize( UINT32 cbTotalSize; // Add up each element. // Find out how large the name will be. - cbTotalSize = ::WideCharToMultiByte(CP_ACP, 0, szStreamName, -1, 0, 0, 0, 0); + cbTotalSize = (UINT32)minipal_get_length_utf16_to_utf8((const CHAR16_T*)szStreamName, u16_strlen(szStreamName) + 1, 0); _ASSERTE(cbTotalSize != 0); // Add the size of the stream header minus the static name array. @@ -445,7 +445,7 @@ HRESULT STDMETHODCALLTYPE TiggerStorage::CreateStream( { #ifdef FEATURE_METADATA_PERSISTENCE char rcStream[MAXSTREAMNAME];// For converted name. - VERIFY(WideCharToMultiByte(CP_ACP, 0, pwcsName, -1, rcStream, sizeof(rcStream), 0, 0)); + VERIFY(minipal_convert_utf16_to_utf8((const CHAR16_T*)pwcsName, u16_strlen(pwcsName) + 1, rcStream, sizeof(rcStream), 0)); return (CreateStream(rcStream, grfMode, reserved1, reserved2, ppstm)); #else return E_NOTIMPL; @@ -641,7 +641,7 @@ HRESULT STDMETHODCALLTYPE TiggerStorage::OpenStream( HRESULT hr; // Convert the name for internal use. - VERIFY(::WideCharToMultiByte(CP_ACP, 0, szStream, -1, rcName, sizeof(rcName), 0, 0)); + VERIFY(minipal_convert_utf16_to_utf8((const CHAR16_T*)szStream, u16_strlen(szStream) + 1, rcName, sizeof(rcName), 0)); // Look for the stream which must be found for this to work. Note that // this error is explicitly not posted as an error object since unfound streams diff --git a/src/coreclr/md/runtime/metamodelro.cpp b/src/coreclr/md/runtime/metamodelro.cpp index 2f3638c331957c..986756b03bac57 100644 --- a/src/coreclr/md/runtime/metamodelro.cpp +++ b/src/coreclr/md/runtime/metamodelro.cpp @@ -102,6 +102,7 @@ CMiniMd::Impl_GetStringW( ULONG *pcchBuffer) { LPCSTR szString; // Single byte version. + size_t cchString; // Length of the single byte version, including the terminator. int iSize; // Size of resulting string, in wide chars. HRESULT hr = NOERROR; @@ -116,19 +117,16 @@ CMiniMd::Impl_GetStringW( *pcchBuffer = 0; goto ErrExit; } - iSize = ::MultiByteToWideChar(CP_UTF8, 0, szString, -1, szOut, cchBuffer); + cchString = strlen(szString) + 1; + if (cchBuffer == 0) + iSize = (int)minipal_get_length_utf8_to_utf16(szString, cchString, 0); + else + iSize = (int)minipal_convert_utf8_to_utf16(szString, cchString, (CHAR16_T*)szOut, cchBuffer, 0); if (iSize == 0) { - // What was the problem? - DWORD dwNT = GetLastError(); - - // Not truncation? - if (dwNT != ERROR_INSUFFICIENT_BUFFER) - IfFailGo(HRESULT_FROM_NT(dwNT)); - // Truncation error; get the size required. if (pcchBuffer != NULL) - *pcchBuffer = ::MultiByteToWideChar(CP_UTF8, 0, szString, -1, NULL, 0); + *pcchBuffer = (ULONG)minipal_get_length_utf8_to_utf16(szString, cchString, 0); if ((szOut != NULL) && (cchBuffer > 0)) { // null-terminate the truncated output string diff --git a/src/coreclr/md/runtime/stgpool.cpp b/src/coreclr/md/runtime/stgpool.cpp index d0d3524ae6ea88..4a12348e670ba7 100644 --- a/src/coreclr/md/runtime/stgpool.cpp +++ b/src/coreclr/md/runtime/stgpool.cpp @@ -986,17 +986,9 @@ StgStringPool::AddStringW( return (S_OK); } - // How many bytes will be required in the heap? - iLen = ::WideCharToMultiByte( - CP_UTF8, - 0, - szString, - -1, // null-terminated string - NULL, - 0, - NULL, - NULL); - // WCTMB includes trailing 0 if (when passing parameter #4 (length) -1. + // How many bytes will be required in the heap, including the trailing 0? + size_t cchString = u16_strlen(szString) + 1; + iLen = (ULONG)minipal_get_length_utf16_to_utf8((const CHAR16_T*)szString, cchString, 0); // Check for room. if (iLen > GetCbSegAvailable()) @@ -1007,17 +999,9 @@ StgStringPool::AddStringW( pData = reinterpret_cast(GetNextLocation()); // Convert the data in place to the correct location. - iLen = ::WideCharToMultiByte( - CP_UTF8, - 0, - szString, - -1, - pData, - GetCbSegAvailable(), - NULL, - NULL); + iLen = (ULONG)minipal_convert_utf16_to_utf8((const CHAR16_T*)szString, cchString, pData, GetCbSegAvailable(), 0); if (iLen == 0) - return (BadError(HRESULT_FROM_NT(GetLastError()))); + return (BadError(HRESULT_FROM_NT(errno))); // If the hash table is to be kept built (default). if (m_bHash) diff --git a/src/coreclr/nativeaot/Runtime/windows/PalCommon.cpp b/src/coreclr/nativeaot/Runtime/windows/PalCommon.cpp index 8e4e582c5cec00..5d30e1dc218e59 100644 --- a/src/coreclr/nativeaot/Runtime/windows/PalCommon.cpp +++ b/src/coreclr/nativeaot/Runtime/windows/PalCommon.cpp @@ -17,6 +17,7 @@ #include #include "CommonMacros.h" #include "rhassert.h" +#include // Given the OS handle of a loaded module, compute the upper and lower virtual address bounds (inclusive). void PalGetModuleBounds(HANDLE hOsHandle, _Out_ uint8_t ** ppLowerBound, _Out_ uint8_t ** ppUpperBound) @@ -160,15 +161,9 @@ void PalGetPDBInfo(HANDLE hOsHandle, GUID * pGuidSignature, _Out_ uint32_t * pdw memcpy(pGuidSignature, &pdbInfoLast.m_pPdb70->signature, sizeof(GUID)); *pdwAge = pdbInfoLast.m_pPdb70->age; - // Convert build path from ANSI (UTF-8) to UNICODE (UTF-16) - int result = MultiByteToWideChar( - CP_UTF8, // Code page for UTF-8 - 0, // No special flags - pdbInfoLast.m_pPdb70->path, // Source UTF-8 string - -1, // Source string length (-1 for null-terminated) - wszPath, // Destination buffer for UTF-16 string - cchPath // Size of destination buffer - ); + // Convert build path from UTF-8 to UTF-16 + const char* path = pdbInfoLast.m_pPdb70->path; + size_t result = minipal_convert_utf8_to_utf16(path, strlen(path) + 1, (CHAR16_T*)wszPath, cchPath, 0); if (result == 0) { diff --git a/src/coreclr/nativeaot/Runtime/windows/PalMinWin.cpp b/src/coreclr/nativeaot/Runtime/windows/PalMinWin.cpp index 529ba14f3f8976..4cbe4991bdffc0 100644 --- a/src/coreclr/nativeaot/Runtime/windows/PalMinWin.cpp +++ b/src/coreclr/nativeaot/Runtime/windows/PalMinWin.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "holder.h" @@ -886,7 +887,7 @@ bool PalSetCurrentThreadName(const char* name) { return false; } - if (MultiByteToWideChar(CP_UTF8, 0, name, -1, threadNameWide, (int)(len + 1)) == 0) + if (minipal_convert_utf8_to_utf16(name, len + 1, (CHAR16_T*)threadNameWide, len + 1, 0) == 0) { delete[] threadNameWide; return false; @@ -939,15 +940,14 @@ void PalPrintFatalError(const char* message) char* PalCopyTCharAsChar(const TCHAR* toCopy) { - int len = ::WideCharToMultiByte(CP_UTF8, 0, toCopy, -1, nullptr, 0, nullptr, nullptr); - if (len == 0) - return nullptr; + size_t length = wcslen(toCopy) + 1; + size_t len = minipal_get_length_utf16_to_utf8((const CHAR16_T*)toCopy, length, 0); char* converted = new (nothrow) char[len]; if (converted != nullptr) { - int written = ::WideCharToMultiByte(CP_UTF8, 0, toCopy, -1, converted, len, nullptr, nullptr); + size_t written = minipal_convert_utf16_to_utf8((const CHAR16_T*)toCopy, length, converted, len, 0); assert(len == written); } return converted; @@ -962,7 +962,7 @@ HANDLE PalLoadLibrary(const char* moduleName) { return 0; } - if (MultiByteToWideChar(CP_UTF8, 0, moduleName, -1, moduleNameWide, (int)(len + 1)) == 0) + if (minipal_convert_utf8_to_utf16(moduleName, len + 1, (CHAR16_T*)moduleNameWide, len + 1, 0) == 0) { return 0; } diff --git a/src/coreclr/nativeresources/resourcestring.cpp b/src/coreclr/nativeresources/resourcestring.cpp index b3089043cc919a..23903f52981217 100644 --- a/src/coreclr/nativeresources/resourcestring.cpp +++ b/src/coreclr/nativeresources/resourcestring.cpp @@ -36,16 +36,15 @@ int LoadNativeStringResource(const NativeStringResourceTable &nativeStringResour if (resourceEntry != NULL) { - len = MultiByteToWideChar(CP_UTF8, 0, resourceEntry->resourceString, -1, szBuffer, iMax); + const char* resourceString = resourceEntry->resourceString; + len = (int)minipal_convert_utf8_to_utf16(resourceString, strlen(resourceString) + 1, (CHAR16_T*)szBuffer, iMax, 0); if (len == 0) { - int hr = HRESULT_FROM_GetLastError(); - // Tell the caller if the buffer isn't big enough - if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) && pcwchUsed) + if (pcwchUsed) *pcwchUsed = iMax; - return hr; + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); } } else diff --git a/src/coreclr/pal/src/cruntime/wchar.cpp b/src/coreclr/pal/src/cruntime/wchar.cpp index aa44b2adc87ef8..aad962fb2b490a 100644 --- a/src/coreclr/pal/src/cruntime/wchar.cpp +++ b/src/coreclr/pal/src/cruntime/wchar.cpp @@ -22,6 +22,7 @@ Module Name: #include #include +#include SET_DEFAULT_DEBUG_CHANNEL(CRT); @@ -43,7 +44,7 @@ _wtoi( PERF_ENTRY(_wtoi); ENTRY("_wtoi (string=%p)\n", string); - len = WideCharToMultiByte(CP_ACP, 0, string, -1, 0, 0, 0, 0); + len = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)string, PAL_wcslen(string) + 1, 0); if (!len) { ASSERT("WideCharToMultiByte failed. Error is %d\n", @@ -57,7 +58,7 @@ _wtoi( SetLastError(ERROR_NOT_ENOUGH_MEMORY); return -1; } - len = WideCharToMultiByte(CP_ACP, 0, string, -1, tempStr, len, 0, 0); + len = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)string, PAL_wcslen(string) + 1, tempStr, len, 0); if (!len) { ASSERT("WideCharToMultiByte failed. Error is %d\n", @@ -247,7 +248,7 @@ PAL_wcstoul( ENTRY("wcstoul (nptr=%p (%S), endptr=%p, base=%d)\n", nptr?nptr:W16_NULLSTRING, nptr?nptr:W16_NULLSTRING, endptr, base); - size = WideCharToMultiByte(CP_ACP, 0, nptr, -1, NULL, 0, NULL, NULL); + size = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, 0); if (!size) { dwLastError = GetLastError(); @@ -264,7 +265,7 @@ PAL_wcstoul( res = 0; goto PAL_wcstoulExit; } - size = WideCharToMultiByte(CP_ACP, 0, nptr, -1, s_nptr, size, NULL, NULL); + size = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, s_nptr, size, 0); if (!size) { dwLastError = GetLastError(); @@ -337,7 +338,7 @@ PAL__wcstoui64( ENTRY("_wcstoui64 (nptr=%p (%S), endptr=%p, base=%d)\n", nptr?nptr:W16_NULLSTRING, nptr?nptr:W16_NULLSTRING, endptr, base); - size = WideCharToMultiByte(CP_ACP, 0, nptr, -1, NULL, 0, NULL, NULL); + size = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, 0); if (!size) { dwLastError = GetLastError(); @@ -354,7 +355,7 @@ PAL__wcstoui64( res = 0; goto PAL__wcstoui64Exit; } - size = WideCharToMultiByte(CP_ACP, 0, nptr, -1, s_nptr, size, NULL, NULL); + size = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, s_nptr, size, 0); if (!size) { dwLastError = GetLastError(); @@ -860,9 +861,8 @@ PAL_wcstod( const wchar_16 * nptr, wchar_16 **endptr ) if ( lpStringRep ) { - if ( WideCharToMultiByte( CP_ACP, 0, lpStartOfExpression, Length, - lpStringRep, Length + 1 , - NULL, 0 ) != 0 ) + if ( minipal_convert_utf16_to_utf8( (const CHAR16_T*)lpStartOfExpression, Length, + lpStringRep, Length + 1, 0 ) != 0 ) { LPSTR ScanStop = NULL; lpStringRep[Length]= 0; diff --git a/src/coreclr/pal/src/debug/debug.cpp b/src/coreclr/pal/src/debug/debug.cpp index cebc8503b5262e..5b697d3cdc3adb 100644 --- a/src/coreclr/pal/src/debug/debug.cpp +++ b/src/coreclr/pal/src/debug/debug.cpp @@ -25,6 +25,7 @@ SET_DEFAULT_DEBUG_CHANNEL(DEBUG); // some headers have code with asserts, so do #include "pal/stackstring.hpp" #include "pal/utils.h" #include +#include #include #include @@ -184,8 +185,7 @@ OutputDebugStringW( goto EXIT; } - if ((strLen = WideCharToMultiByte(CP_ACP, 0, lpOutputString, -1, NULL, 0, - NULL, NULL)) + if ((strLen = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpOutputString, PAL_wcslen(lpOutputString) + 1, 0)) == 0) { ASSERT("failed to get wide chars length\n"); @@ -201,8 +201,8 @@ OutputDebugStringW( goto EXIT; } - if(! WideCharToMultiByte(CP_ACP, 0, lpOutputString, -1, - lpOutputStringA, strLen, NULL, NULL)) + if(! minipal_convert_utf16_to_utf8((const CHAR16_T*)lpOutputString, PAL_wcslen(lpOutputString) + 1, + lpOutputStringA, strLen, 0)) { ASSERT("failed to convert wide chars to multibytes\n"); SetLastError(ERROR_INTERNAL_ERROR); diff --git a/src/coreclr/pal/src/file/directory.cpp b/src/coreclr/pal/src/file/directory.cpp index e06afd0b19e1c2..482b4a0d7077e4 100644 --- a/src/coreclr/pal/src/file/directory.cpp +++ b/src/coreclr/pal/src/file/directory.cpp @@ -23,6 +23,7 @@ Revision History: #include "pal/dbgmsg.h" #include "pal/file.h" #include "pal/stackstring.hpp" +#include #include #include @@ -67,8 +68,7 @@ CreateDirectoryW( } /* translate the wide char lpPathName string to multibyte string */ - if(0 == (mb_size = WideCharToMultiByte( CP_ACP, 0, lpPathName, -1, NULL, 0, - NULL, NULL ))) + if(0 == (mb_size = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpPathName, PAL_wcslen(lpPathName) + 1, 0))) { ASSERT("WideCharToMultiByte failure! error is %d\n", GetLastError()); dwLastError = ERROR_INTERNAL_ERROR; @@ -76,8 +76,7 @@ CreateDirectoryW( } if (((mb_dir = (char *)malloc(mb_size)) == NULL) || - (WideCharToMultiByte( CP_ACP, 0, lpPathName, -1, mb_dir, mb_size, NULL, - NULL) != mb_size)) + ((int)minipal_convert_utf16_to_utf8((const CHAR16_T*)lpPathName, PAL_wcslen(lpPathName) + 1, mb_dir, mb_size, 0) != mb_size)) { ASSERT("WideCharToMultiByte or malloc failure! LastError:%d errno:%d\n", GetLastError(), errno); @@ -208,8 +207,7 @@ RemoveDirectoryW( goto done; } - mb_size = WideCharToMultiByte( CP_ACP, 0, lpPathName, -1, mb_dir, length, - NULL, NULL ); + mb_size = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)lpPathName, PAL_wcslen(lpPathName) + 1, mb_dir, length, 0); if( mb_size == 0 ) { @@ -335,8 +333,7 @@ SetCurrentDirectoryW( goto done; } - size = WideCharToMultiByte( CP_ACP, 0, lpPathName, -1, dir, length, - NULL, NULL ); + size = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)lpPathName, PAL_wcslen(lpPathName) + 1, dir, length, 0); if( size == 0 ) { diff --git a/src/coreclr/pal/src/file/file.cpp b/src/coreclr/pal/src/file/file.cpp index f7e524d1152408..ceb75c5913db03 100644 --- a/src/coreclr/pal/src/file/file.cpp +++ b/src/coreclr/pal/src/file/file.cpp @@ -19,6 +19,7 @@ SET_DEFAULT_DEBUG_CHANNEL(FILE); // some headers have code with asserts, so do t #include "pal/palinternal.h" #include "pal/file.h" #include "pal/utils.h" +#include #include #include @@ -839,8 +840,7 @@ CreateFileW( goto done; } - size = WideCharToMultiByte( CP_ACP, 0, lpFileName, -1, name, length, - NULL, NULL ); + size = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)lpFileName, PAL_wcslen(lpFileName) + 1, name, length, 0); if( size == 0 ) { diff --git a/src/coreclr/pal/src/file/path.cpp b/src/coreclr/pal/src/file/path.cpp index ff4e0dad2542a8..d5dbfeaae77d9f 100644 --- a/src/coreclr/pal/src/file/path.cpp +++ b/src/coreclr/pal/src/file/path.cpp @@ -14,6 +14,7 @@ Module Name: #include "pal/dbgmsg.h" #include "pal/file.h" #include "pal/stackstring.hpp" +#include #include @@ -178,8 +179,7 @@ GetFullPathNameW( lpBuffer, lpFilePart); - fileNameLength = WideCharToMultiByte(CP_ACP, 0, lpFileName, - -1, NULL, 0, NULL, NULL); + fileNameLength = lpFileName != NULL ? (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpFileName, PAL_wcslen(lpFileName) + 1, 0) : 0; if (fileNameLength == 0) { /* Couldn't convert to ANSI. That's odd. */ @@ -192,9 +192,7 @@ GetFullPathNameW( } /* Now convert lpFileName to ANSI. */ - srcSize = WideCharToMultiByte (CP_ACP, 0, lpFileName, - -1, fileNameA, fileNameLength, - NULL, NULL ); + srcSize = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)lpFileName, PAL_wcslen(lpFileName) + 1, fileNameA, fileNameLength, 0); if( srcSize == 0 ) { DWORD dwLastError = GetLastError(); @@ -221,23 +219,21 @@ GetFullPathNameW( } /* Convert back to Unicode the result */ - nRet = MultiByteToWideChar( CP_ACP, 0, bufferA, -1, - lpBuffer, nBufferLength ); + nRet = (DWORD)minipal_convert_utf8_to_utf16(bufferA, strlen(bufferA) + 1, (CHAR16_T*)lpBuffer, nBufferLength, 0); if (nRet == 0) { if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) { /* get the required length */ - nRet = MultiByteToWideChar( CP_ACP, 0, bufferA, -1, - NULL, 0 ); + nRet = (DWORD)minipal_get_length_utf8_to_utf16(bufferA, strlen(bufferA) + 1, 0); SetLastError(ERROR_BUFFER_OVERFLOW); } goto done; } - /* MultiByteToWideChar counts the trailing NULL, but + /* The converted length counts the trailing NULL, but GetFullPathName does not. */ nRet--; @@ -245,8 +241,7 @@ GetFullPathNameW( if (lpFilePart != NULL) { *lpFilePart = lpBuffer; - *lpFilePart += MultiByteToWideChar( CP_ACP, 0, bufferA, - lpFilePartA - bufferA, NULL, 0); + *lpFilePart += minipal_get_length_utf8_to_utf16(bufferA, lpFilePartA - bufferA, 0); } done: @@ -602,8 +597,7 @@ SearchPathW( SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto done; } - canonical_size = WideCharToMultiByte(CP_ACP, 0, CanonicalPath, -1, - AnsiPath, CanonicalPathLength, NULL, NULL); + canonical_size = minipal_convert_utf16_to_utf8((const CHAR16_T*)CanonicalPath, PAL_wcslen(CanonicalPath) + 1, AnsiPath, CanonicalPathLength, 0); AnsiPathPS.CloseBuffer(canonical_size); if(0 == access(AnsiPath, F_OK)) @@ -702,8 +696,7 @@ SearchPathW( SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto done; } - canonical_size = WideCharToMultiByte(CP_ACP, 0, CanonicalPath, -1, - AnsiPath, CanonicalPathLength, NULL, NULL); + canonical_size = minipal_convert_utf16_to_utf8((const CHAR16_T*)CanonicalPath, PAL_wcslen(CanonicalPath) + 1, AnsiPath, CanonicalPathLength, 0); AnsiPathPS.CloseBuffer(canonical_size); if(0 == access(AnsiPath, F_OK)) diff --git a/src/coreclr/pal/src/include/pal/utils.h b/src/coreclr/pal/src/include/pal/utils.h index 18298997e1c021..1382506af6a10b 100644 --- a/src/coreclr/pal/src/include/pal/utils.h +++ b/src/coreclr/pal/src/include/pal/utils.h @@ -90,7 +90,7 @@ Parameters : Return Value : newly allocated buffer containing the converted string. Conversion is - performed using CP_ACP. Buffer is allocated with malloc(), release it + performed using UTF-8. Buffer is allocated with malloc(), release it with free(). In case if failure, LastError will be set. --*/ @@ -109,7 +109,7 @@ Parameters : Return Value : newly allocated buffer containing the converted string. Conversion is - performed using CP_ACP. Buffer is allocated with malloc(), release it + performed using UTF-8. Buffer is allocated with malloc(), release it with free(). In case if failure, LastError will be set. --*/ diff --git a/src/coreclr/pal/src/init/pal.cpp b/src/coreclr/pal/src/init/pal.cpp index 0d9c9fb6359d53..0875b3a9656ddd 100644 --- a/src/coreclr/pal/src/init/pal.cpp +++ b/src/coreclr/pal/src/init/pal.cpp @@ -23,6 +23,7 @@ SET_DEFAULT_DEBUG_CHANNEL(PAL); // some headers have code with asserts, so do th #include "../thread/procprivate.hpp" #include "pal/module.h" #include "pal/environ.h" +#include #include "pal/utils.h" #include "pal/debug.h" #include "pal/init.h" @@ -729,7 +730,7 @@ static LPWSTR INIT_GetCurrentEXEPath() real_path.Set(path, strlen(path)); free(path); - return_size = MultiByteToWideChar(CP_ACP, 0, real_path, -1, nullptr, 0); + return_size = (INT)minipal_get_length_utf8_to_utf16(real_path, strlen(real_path) + 1, 0); if (0 == return_size) { ASSERT("MultiByteToWideChar failure\n"); @@ -744,8 +745,7 @@ static LPWSTR INIT_GetCurrentEXEPath() } else { - if (!MultiByteToWideChar(CP_ACP, 0, real_path, -1, - return_value, return_size)) + if (!minipal_convert_utf8_to_utf16(real_path, strlen(real_path) + 1, (CHAR16_T*)return_value, return_size, 0)) { ASSERT("MultiByteToWideChar failure\n"); free(return_value); diff --git a/src/coreclr/pal/src/loader/module.cpp b/src/coreclr/pal/src/loader/module.cpp index d31ae4373a1cac..334b9e0fc09844 100644 --- a/src/coreclr/pal/src/loader/module.cpp +++ b/src/coreclr/pal/src/loader/module.cpp @@ -31,6 +31,7 @@ SET_DEFAULT_DEBUG_CHANNEL(LOADER); // some headers have code with asserts, so do #include "pal/environ.h" #include "pal/map.hpp" #include "pal/stackstring.hpp" +#include #include #include @@ -406,8 +407,7 @@ GetModuleFileNameA( /* Convert module name to Ascii, place it in the supplied buffer */ - name_length = WideCharToMultiByte(CP_ACP, 0, wide_name, -1, lpFileName, - nSize, nullptr, nullptr); + name_length = (INT)minipal_convert_utf16_to_utf8((const CHAR16_T*)wide_name, PAL_wcslen(wide_name) + 1, lpFileName, nSize, 0); if (name_length == 0) { TRACE("Buffer too small to copy module's file name.\n"); @@ -1295,8 +1295,7 @@ static bool LOADConvertLibraryPathWideStringToMultibyteString( _ASSERTE(wideLibraryPath != nullptr); size_t length = (PAL_wcslen(wideLibraryPath)+1) * MaxWCharToAcpLength; - *multibyteLibraryPathLengthRef = WideCharToMultiByte(CP_ACP, 0, wideLibraryPath, -1, multibyteLibraryPath, - length, nullptr, nullptr); + *multibyteLibraryPathLengthRef = (INT)minipal_convert_utf16_to_utf8((const CHAR16_T*)wideLibraryPath, PAL_wcslen(wideLibraryPath) + 1, multibyteLibraryPath, length, 0); if (*multibyteLibraryPathLengthRef == 0) { diff --git a/src/coreclr/pal/src/misc/environ.cpp b/src/coreclr/pal/src/misc/environ.cpp index 919496a124f7bb..d22bb658e51fe5 100644 --- a/src/coreclr/pal/src/misc/environ.cpp +++ b/src/coreclr/pal/src/misc/environ.cpp @@ -12,6 +12,7 @@ Module Name: #include "pal/palinternal.h" #include "pal/dbgmsg.h" #include "pal/environ.h" +#include #if HAVE_CRT_EXTERNS_H #include @@ -162,8 +163,7 @@ GetEnvironmentVariableW( lpName ? lpName : W16_NULLSTRING, lpName ? lpName : W16_NULLSTRING, lpBuffer, nSize); - inBuffSize = WideCharToMultiByte(CP_ACP, 0, lpName, -1, - inBuff, 0, nullptr, nullptr); + inBuffSize = lpName != nullptr ? (INT)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpName, PAL_wcslen(lpName) + 1, 0) : 0; if (0 == inBuffSize) { ERROR("lpName has to be a valid parameter\n"); @@ -190,8 +190,7 @@ GetEnvironmentVariableW( } } - if (0 == WideCharToMultiByte(CP_ACP, 0, lpName, -1, inBuff, - inBuffSize, nullptr, nullptr)) + if (0 == minipal_convert_utf16_to_utf8((const CHAR16_T*)lpName, PAL_wcslen(lpName) + 1, inBuff, inBuffSize, 0)) { ASSERT("WideCharToMultiByte failed!\n"); SetLastError(ERROR_INTERNAL_ERROR); @@ -215,7 +214,7 @@ GetEnvironmentVariableW( } else { - size = MultiByteToWideChar(CP_ACP, 0, outBuff, -1, lpBuffer, nSize); + size = (DWORD)minipal_convert_utf8_to_utf16(outBuff, strlen(outBuff) + 1, (CHAR16_T*)lpBuffer, nSize, 0); if (0 != size) { // -1 for the null. @@ -290,8 +289,7 @@ SetEnvironmentVariableW( lpName?lpName:W16_NULLSTRING, lpName?lpName:W16_NULLSTRING, lpValue?lpValue:W16_NULLSTRING, lpValue?lpValue:W16_NULLSTRING); - if ((nameSize = WideCharToMultiByte(CP_ACP, 0, lpName, -1, name, 0, - nullptr, nullptr)) == 0) + if ((nameSize = lpName != nullptr ? (INT)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpName, PAL_wcslen(lpName) + 1, 0) : 0) == 0) { ERROR("WideCharToMultiByte failed\n"); SetLastError(ERROR_INVALID_PARAMETER); @@ -306,8 +304,7 @@ SetEnvironmentVariableW( goto done; } - if (0 == WideCharToMultiByte(CP_ACP, 0, lpName, -1, - name, nameSize, nullptr, nullptr)) + if (0 == minipal_convert_utf16_to_utf8((const CHAR16_T*)lpName, PAL_wcslen(lpName) + 1, name, nameSize, 0)) { ASSERT("WideCharToMultiByte returned 0\n"); SetLastError(ERROR_INTERNAL_ERROR); @@ -316,8 +313,7 @@ SetEnvironmentVariableW( if (lpValue != nullptr) { - if ((valueSize = WideCharToMultiByte(CP_ACP, 0, lpValue, -1, value, - 0, nullptr, nullptr)) == 0) + if ((valueSize = (INT)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpValue, PAL_wcslen(lpValue) + 1, 0)) == 0) { ERROR("WideCharToMultiByte failed\n"); SetLastError(ERROR_INVALID_PARAMETER); @@ -333,8 +329,7 @@ SetEnvironmentVariableW( goto done; } - if (0 == WideCharToMultiByte(CP_ACP, 0, lpValue, -1, - value, valueSize, nullptr, nullptr)) + if (0 == minipal_convert_utf16_to_utf8((const CHAR16_T*)lpValue, PAL_wcslen(lpValue) + 1, value, valueSize, 0)) { ASSERT("WideCharToMultiByte failed\n"); SetLastError( ERROR_INTERNAL_ERROR ); @@ -398,7 +393,7 @@ GetEnvironmentStringsW( /* get total length of the bytes that we need to allocate */ for (i = 0; palEnvironment[i] != 0; i++) { - len = MultiByteToWideChar(CP_ACP, 0, palEnvironment[i], -1, wenviron, 0); + len = (int)minipal_get_length_utf8_to_utf16(palEnvironment[i], strlen(palEnvironment[i]) + 1, 0); envNum += len; } @@ -414,7 +409,7 @@ GetEnvironmentStringsW( tempEnviron = wenviron; for (i = 0; palEnvironment[i] != 0; i++) { - len = MultiByteToWideChar(CP_ACP, 0, palEnvironment[i], -1, tempEnviron, envNum); + len = (int)minipal_convert_utf8_to_utf16(palEnvironment[i], strlen(palEnvironment[i]) + 1, (CHAR16_T*)tempEnviron, envNum, 0); tempEnviron += len; envNum -= len; } diff --git a/src/coreclr/pal/src/misc/fmtmessage.cpp b/src/coreclr/pal/src/misc/fmtmessage.cpp index f096156f23847e..1e8d6cf48a3223 100644 --- a/src/coreclr/pal/src/misc/fmtmessage.cpp +++ b/src/coreclr/pal/src/misc/fmtmessage.cpp @@ -22,6 +22,7 @@ Revision History: #include "pal/palinternal.h" #include "pal/dbgmsg.h" #include "pal/module.h" +#include #include "errorstrings.h" @@ -106,8 +107,7 @@ static INT FMTMSG__watoi( LPWSTR str ) CHAR buf[ MAX_NUMBER_LENGTH ]; INT nRetVal = 0; - nRetVal = WideCharToMultiByte( CP_ACP, 0, str, -1, buf, - MAX_NUMBER_LENGTH, NULL, 0 ); + nRetVal = (INT)minipal_convert_utf16_to_utf8((const CHAR16_T*)str, PAL_wcslen(str) + 1, buf, MAX_NUMBER_LENGTH, 0); if ( nRetVal != 0 ) { diff --git a/src/coreclr/pal/src/misc/utils.cpp b/src/coreclr/pal/src/misc/utils.cpp index fb5b2273cb7fae..c05b0b1d60ff2b 100644 --- a/src/coreclr/pal/src/misc/utils.cpp +++ b/src/coreclr/pal/src/misc/utils.cpp @@ -27,6 +27,7 @@ SET_DEFAULT_DEBUG_CHANNEL(MISC); // some headers have code with asserts, so do t #include #include +#include // In safemath.h, Template SafeInt uses macro _ASSERTE, which need to use variable @@ -47,18 +48,18 @@ Parameters : Return Value : newly allocated buffer containing the converted string. Conversion is - performed using CP_ACP. Buffer is allocated with malloc(), release it + performed using UTF-8. Buffer is allocated with malloc(), release it with free(). In case if failure, LastError will be set. --*/ LPSTR UTIL_WCToMB_Alloc(LPCWSTR lpWideCharStr, int cchWideChar) { + size_t cchSource = cchWideChar < 0 ? PAL_wcslen(lpWideCharStr) + 1 : (size_t)cchWideChar; int length; LPSTR lpMultiByteStr; /* get required buffer length */ - length = WideCharToMultiByte(CP_ACP, 0, lpWideCharStr, cchWideChar, - NULL, 0, NULL, NULL); + length = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpWideCharStr, cchSource, 0); if(0 == length) { ERROR("WCToMB error; GetLastError returns %#x", GetLastError()); @@ -75,8 +76,7 @@ LPSTR UTIL_WCToMB_Alloc(LPCWSTR lpWideCharStr, int cchWideChar) } /* convert into allocated buffer */ - length = WideCharToMultiByte(CP_ACP, 0, lpWideCharStr, cchWideChar, - lpMultiByteStr, length, NULL, NULL); + length = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)lpWideCharStr, cchSource, lpMultiByteStr, length, 0); if(0 == length) { ASSERT("WCToMB error; GetLastError returns %#x\n", GetLastError()); @@ -99,18 +99,18 @@ Parameters : Return Value : newly allocated buffer containing the converted string. Conversion is - performed using CP_ACP. Buffer is allocated with malloc(), release it + performed using UTF-8. Buffer is allocated with malloc(), release it with free(). In case if failure, LastError will be set. --*/ LPWSTR UTIL_MBToWC_Alloc(LPCSTR lpMultiByteStr, int cbMultiByte) { + size_t cbSource = cbMultiByte < 0 ? strlen(lpMultiByteStr) + 1 : (size_t)cbMultiByte; int length; LPWSTR lpWideCharStr; /* get required buffer length */ - length = MultiByteToWideChar(CP_ACP, 0, lpMultiByteStr, cbMultiByte, - NULL, 0); + length = (int)minipal_get_length_utf8_to_utf16(lpMultiByteStr, cbSource, 0); if(0 == length) { ERROR("MBToWC error; GetLastError returns %#x", GetLastError()); @@ -135,8 +135,7 @@ LPWSTR UTIL_MBToWC_Alloc(LPCSTR lpMultiByteStr, int cbMultiByte) } /* convert into allocated buffer */ - length = MultiByteToWideChar(CP_ACP, 0, lpMultiByteStr, cbMultiByte, - lpWideCharStr, length); + length = (int)minipal_convert_utf8_to_utf16(lpMultiByteStr, cbSource, (CHAR16_T*)lpWideCharStr, length, 0); if(0 >= length) { ASSERT("MCToMB error; GetLastError returns %#x\n", GetLastError()); diff --git a/src/coreclr/pal/src/thread/thread.cpp b/src/coreclr/pal/src/thread/thread.cpp index cb21db893f0f49..5eb7fa9f4f6ecb 100644 --- a/src/coreclr/pal/src/thread/thread.cpp +++ b/src/coreclr/pal/src/thread/thread.cpp @@ -24,6 +24,7 @@ SET_DEFAULT_DEBUG_CHANNEL(THREAD); // some headers have code with asserts, so do #include "pal/module.h" #include "pal/environ.h" #include "pal/init.h" +#include #include "pal/utils.h" #include @@ -1312,11 +1313,11 @@ SetThreadDescription( // it causes the value returned by Process.ProcessName to change. if ((pid_t)pTargetThread->GetThreadId() != getpid()) { - nameSize = WideCharToMultiByte(CP_ACP, 0, lpThreadDescription, -1, NULL, 0, NULL, NULL); + nameSize = lpThreadDescription != NULL ? (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpThreadDescription, PAL_wcslen(lpThreadDescription) + 1, 0) : 0; if (nameSize > 0) { nameBuf = (char *)malloc(nameSize); - if (nameBuf == NULL || WideCharToMultiByte(CP_ACP, 0, lpThreadDescription, -1, nameBuf, nameSize, NULL, NULL) != nameSize) + if (nameBuf == NULL || (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)lpThreadDescription, PAL_wcslen(lpThreadDescription) + 1, nameBuf, nameSize, 0) != nameSize) { pThread->SetLastError(ERROR_INSUFFICIENT_BUFFER); } diff --git a/src/coreclr/pal/tests/palsuite/common/palsuite.cpp b/src/coreclr/pal/tests/palsuite/common/palsuite.cpp index 6d05884b5c28ee..88c41e3425e4e0 100644 --- a/src/coreclr/pal/tests/palsuite/common/palsuite.cpp +++ b/src/coreclr/pal/tests/palsuite/common/palsuite.cpp @@ -13,6 +13,7 @@ #include "palsuite.h" #include "minipal/time.h" +#include "minipal/utf8.h" const char* szTextFile = "text.txt"; @@ -24,13 +25,14 @@ WCHAR* convert(const char * aString) if (aString != nullptr) { - int size = MultiByteToWideChar(CP_ACP,0,aString,-1,NULL,0); + size_t length = strlen(aString) + 1; + size_t size = minipal_get_length_utf8_to_utf16(aString, length, 0); wideBuffer = (WCHAR*) malloc(size*sizeof(WCHAR)); if (wideBuffer == NULL) { Fail("ERROR: Unable to allocate memory!\n"); } - MultiByteToWideChar(CP_ACP,0,aString,-1,wideBuffer,size); + minipal_convert_utf8_to_utf16(aString, length, (CHAR16_T*)wideBuffer, size, 0); } return wideBuffer; @@ -38,16 +40,14 @@ WCHAR* convert(const char * aString) char* convertC(const WCHAR * wString) { - int size; - char * MultiBuffer = NULL; - - size = WideCharToMultiByte(CP_ACP,0,wString,-1,MultiBuffer,0,NULL,NULL); - MultiBuffer = (char*) malloc(size); + size_t length = wcslen(wString) + 1; + size_t size = minipal_get_length_utf16_to_utf8((const CHAR16_T*)wString, length, 0); + char * MultiBuffer = (char*) malloc(size); if (MultiBuffer == NULL) { Fail("ERROR: Unable to allocate memory!\n"); } - WideCharToMultiByte(CP_ACP,0,wString,-1,MultiBuffer,size,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wString, length, MultiBuffer, size, 0); return MultiBuffer; } @@ -206,7 +206,7 @@ DeleteFileW( CHAR mbFileName[ MAX_PATH ]; - if (WideCharToMultiByte( CP_ACP, 0, lpFileName, -1, mbFileName, sizeof(mbFileName), NULL, NULL ) != 0 ) + if (minipal_convert_utf16_to_utf8((const CHAR16_T*)lpFileName, wcslen(lpFileName) + 1, mbFileName, sizeof(mbFileName), 0) != 0) { return remove(mbFileName) == 0; } diff --git a/src/coreclr/scripts/genLttngProvider.py b/src/coreclr/scripts/genLttngProvider.py index 24030925a22cdf..c782d9be97f18f 100644 --- a/src/coreclr/scripts/genLttngProvider.py +++ b/src/coreclr/scripts/genLttngProvider.py @@ -343,10 +343,10 @@ def generateMethodBody(template, providerName, eventName, runtimeFlavor): if ctf_type == "ctf_string" and wintypeName == "win:UnicodeString": #emit code to convert unicode to ansi string - result.append(" " + paramname+ "_path_size = WideCharToMultiByte( CP_ACP, 0, ") - result.append(paramname + ", -1, ") + result.append(" " + paramname + "_path_size = (INT)minipal_convert_utf16_to_utf8((const CHAR16_T*)") + result.append(paramname + ", lttng_strlen16(" + paramname + ") + 1, ") result.append(paramname + "_full_name, ") - result.append(paramname + "_full_name_path_size, NULL, NULL );\n") + result.append(paramname + "_full_name_path_size, 0);\n") result.append(" _ASSERTE(" +paramname+ "_path_size < " ) result.append(paramname + "_full_name_path_size );\n ") @@ -581,6 +581,7 @@ def generateLttngFiles(etwmanifest, eventprovider_directory, runtimeFlavor, dryR #include "pal_error.h" #include "pal.h" #include "pal/stackstring.hpp" +#include """) lttngimpl_file.write("#include \"" + lttngevntheadershortname + "\"\n\n") diff --git a/src/coreclr/tools/metainfo/mdinfo.cpp b/src/coreclr/tools/metainfo/mdinfo.cpp index c28e71f7549ec3..35f4d65d435340 100644 --- a/src/coreclr/tools/metainfo/mdinfo.cpp +++ b/src/coreclr/tools/metainfo/mdinfo.cpp @@ -198,7 +198,7 @@ const char *g_szNativeType[] = static const char* ConvertToUtf8(LPCWSTR name, _Out_writes_(bufLen) char* buffer, ULONG bufLen) { - int res = WideCharToMultiByte(CP_UTF8, 0, name, -1, buffer, bufLen, NULL, NULL); + size_t res = minipal_convert_utf16_to_utf8((const CHAR16_T*)name, u16_strlen(name) + 1, buffer, bufLen, 0); if (res == 0) buffer[0] = '\0'; return buffer; @@ -1955,7 +1955,7 @@ void MDInfo::DisplayCustomAttributeInfo(mdCustomAttribute inValue, const char *p LPWSTR pwzName = (LPWSTR)(new WCHAR[iLen]); if(pwzName) { - MultiByteToWideChar(CP_UTF8,0, pMethName,-1, pwzName,iLen); + minipal_convert_utf8_to_utf16(pMethName, strlen(pMethName) + 1, (CHAR16_T*)pwzName, iLen, 0); PrettyPrintSigLegacy(pSig, cbSig, pwzName, &qSigName, m_pImport); delete [] pwzName; } diff --git a/src/coreclr/tools/metainfo/mdobj.cpp b/src/coreclr/tools/metainfo/mdobj.cpp index 8d9d604280213b..18a9c04d81c52c 100644 --- a/src/coreclr/tools/metainfo/mdobj.cpp +++ b/src/coreclr/tools/metainfo/mdobj.cpp @@ -208,8 +208,7 @@ void DisplayArchive(_In_z_ WCHAR* szFile, ULONG DumpFilter, _In_opt_z_ WCHAR* sz { if((szName = GetNameOfObj(pbLongNameAddress, (PIMAGE_ARCHIVE_MEMBER_HEADER)pbMapAddress, szBuf))!=NULL) { - if (MultiByteToWideChar(CP_ACP, 0, szName, -1, wzName, 1024) == -1) - MDInfo::Error("Conversion from Multi-Byte to Wide-Char failed."); + minipal_convert_utf8_to_utf16(szName, strlen(szName) + 1, (CHAR16_T*)wzName, 1024, 0); // Display metadata only for object files. // If szObjName is specified, display metadata only for that one object file. diff --git a/src/coreclr/tools/superpmi/mcs/verbmerge.cpp b/src/coreclr/tools/superpmi/mcs/verbmerge.cpp index 35b7263d4a68b7..08866c66e81a61 100644 --- a/src/coreclr/tools/superpmi/mcs/verbmerge.cpp +++ b/src/coreclr/tools/superpmi/mcs/verbmerge.cpp @@ -8,6 +8,7 @@ #include "spmiutil.h" #include "config.h" #include +#include #ifdef TARGET_UNIX #include #include @@ -44,21 +45,21 @@ LPWSTR verbMerge::MergePathStrings(LPCWSTR dir, LPCWSTR file) return newpath; } -char* verbMerge::ConvertWideCharToMultiByte(LPCWSTR wstr) +char* verbMerge::ConvertToUtf8(LPCWSTR wstr) { - unsigned int codePage = CP_UTF8; - int sizeNeeded = WideCharToMultiByte(codePage, 0, wstr, -1, NULL, 0, NULL, NULL); - char* encodedStr = new char[sizeNeeded]; - WideCharToMultiByte(codePage, 0, wstr, -1, encodedStr, sizeNeeded, NULL, NULL); + size_t length = u16_strlen(wstr) + 1; + size_t sizeNeeded = minipal_get_length_utf16_to_utf8((const CHAR16_T*)wstr, length, 0); + char* encodedStr = new char[sizeNeeded]; + minipal_convert_utf16_to_utf8((const CHAR16_T*)wstr, length, encodedStr, sizeNeeded, 0); return encodedStr; } -WCHAR* verbMerge::ConvertMultiByteToWideChar(LPCSTR str) +WCHAR* verbMerge::ConvertFromUtf8(LPCSTR str) { - unsigned int codePage = CP_UTF8; - int sizeNeeded = MultiByteToWideChar(codePage, 0, str, -1, NULL, 0); - WCHAR* encodedStr = new WCHAR[sizeNeeded]; - MultiByteToWideChar(codePage, 0, str, -1, encodedStr, sizeNeeded); + size_t length = strlen(str) + 1; + size_t sizeNeeded = minipal_get_length_utf8_to_utf16(str, length, 0); + WCHAR* encodedStr = new WCHAR[sizeNeeded]; + minipal_convert_utf8_to_utf16(str, length, (CHAR16_T*)encodedStr, sizeNeeded, 0); return encodedStr; } @@ -73,7 +74,7 @@ int verbMerge::AppendFileRaw(HANDLE hFileOut, LPCWSTR fileFullPath, unsigned cha { int result = 0; // default to zero == success - char* fileNameAsChar = ConvertWideCharToMultiByte(fileFullPath); + char* fileNameAsChar = ConvertToUtf8(fileFullPath); LogInfo("Appending file '%s'", fileNameAsChar); HANDLE hFileIn = CreateFileW(fileFullPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, @@ -146,7 +147,7 @@ int verbMerge::AppendFile(HANDLE hFileOut, LPCWSTR fileFullPath, bool dedup, uns if (dedup) { // Need to conver the fileFullPath to non-Unicode. - char* fileFullPathAsChar = ConvertWideCharToMultiByte(fileFullPath); + char* fileFullPathAsChar = ConvertToUtf8(fileFullPath); LogInfo("Appending file '%s'", fileFullPathAsChar); bool ok = m_removeDups.CopyAndRemoveDups(fileFullPathAsChar, hFileOut); delete[] fileFullPathAsChar; @@ -329,7 +330,7 @@ int verbMerge::FilterDirectory(LPCWSTR dir, continue; // Call the filter with &FindData like the Windows code below. - FindData findData(dirEntryType, ConvertMultiByteToWideChar(pEntry->d_name)); + FindData findData(dirEntryType, ConvertFromUtf8(pEntry->d_name)); if (filter(&findData)) { // Prepend it to the list. @@ -513,7 +514,7 @@ int verbMerge::AppendAllInDir(HANDLE hFileOut, #else // TARGET_WINDOWS struct stat fileStat; - char *fileFullPathUtf8 = ConvertWideCharToMultiByte(fileFullPath); + char *fileFullPathUtf8 = ConvertToUtf8(fileFullPath); int st = stat(fileFullPathUtf8, &fileStat); if (st != 0) { @@ -530,7 +531,7 @@ int verbMerge::AppendAllInDir(HANDLE hFileOut, // Is it zero length? If so, skip it. if (fileSize == 0) { - char* fileFullPathAsChar = ConvertWideCharToMultiByte(fileFullPath); + char* fileFullPathAsChar = ConvertToUtf8(fileFullPath); LogInfo("Skipping zero-length file '%s'", fileFullPathAsChar); delete[] fileFullPathAsChar; } @@ -623,13 +624,8 @@ int verbMerge::DoWork(const char* nameOfOutputFile, const char* pattern, bool re } } - int nameLength = (int)strlen(nameOfOutputFile) + 1; - LPWSTR nameOfOutputFileAsWchar = new WCHAR[nameLength]; - MultiByteToWideChar(CP_ACP, 0, nameOfOutputFile, -1, nameOfOutputFileAsWchar, nameLength); - - int patternLength = (int)strlen(pattern) + 1; - LPWSTR patternAsWchar = new WCHAR[patternLength]; - MultiByteToWideChar(CP_ACP, 0, pattern, -1, patternAsWchar, patternLength); + LPWSTR nameOfOutputFileAsWchar = ConvertFromUtf8(nameOfOutputFile); + LPWSTR patternAsWchar = ConvertFromUtf8(pattern); HANDLE hFileOut = CreateFileW(nameOfOutputFileAsWchar, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); diff --git a/src/coreclr/tools/superpmi/mcs/verbmerge.h b/src/coreclr/tools/superpmi/mcs/verbmerge.h index ce1eee96b7c522..4f0147bc8e3959 100644 --- a/src/coreclr/tools/superpmi/mcs/verbmerge.h +++ b/src/coreclr/tools/superpmi/mcs/verbmerge.h @@ -80,8 +80,8 @@ class verbMerge static LPWSTR MergePathStrings(LPCWSTR dir, LPCWSTR file); - static char* ConvertWideCharToMultiByte(LPCWSTR wstr); - static WCHAR* ConvertMultiByteToWideChar(LPCSTR str); + static char* ConvertToUtf8(LPCWSTR wstr); + static WCHAR* ConvertFromUtf8(LPCSTR str); static int AppendFileRaw(HANDLE hFileOut, LPCWSTR fileFullPath, unsigned char* buffer, size_t bufferSize); static int AppendFile(HANDLE hFileOut, LPCWSTR fileFullPath, bool dedup, unsigned char* buffer, size_t bufferSize); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp b/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp index 1044df01ba7581..139319a5288e8e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp @@ -13,6 +13,7 @@ #include #include #include +#include static bool breakOnDebugBreakorAV = false; @@ -585,11 +586,10 @@ std::string getClassName(MethodContext* mc, CORINFO_CLASS_HANDLE clsHnd) std::string ConvertToUtf8(const WCHAR* str) { - unsigned len = WideCharToMultiByte(CP_UTF8, 0, str, -1, nullptr, 0, nullptr, nullptr); - if (len == 0) - return{}; + size_t length = u16_strlen(str) + 1; + size_t len = minipal_get_length_utf16_to_utf8((const CHAR16_T*)str, length, 0); std::vector buf(len + 1); - WideCharToMultiByte(CP_UTF8, 0, str, -1, buf.data(), len + 1, nullptr, nullptr); + minipal_convert_utf16_to_utf8((const CHAR16_T*)str, length, buf.data(), len + 1, 0); return std::string{ buf.data() }; } diff --git a/src/coreclr/tools/superpmi/superpmi/jithost.cpp b/src/coreclr/tools/superpmi/superpmi/jithost.cpp index 5bf155d9d0d1ca..4c7b22ac1282a4 100644 --- a/src/coreclr/tools/superpmi/superpmi/jithost.cpp +++ b/src/coreclr/tools/superpmi/superpmi/jithost.cpp @@ -8,6 +8,7 @@ #include "jithost.h" #include +#include WCHAR* GetPrefixedEnvironmentVariable(const WCHAR* prefix, size_t prefixLen, const WCHAR* key, JitInstance& jitInstance) { @@ -46,18 +47,11 @@ WCHAR* GetPrefixedEnvironmentVariable(const WCHAR* prefix, size_t prefixLen, con // the returned value must be freed with jitInstance.freeLongLivedArray(value). char* GetConfigFromEnvironmentVariable(const char* key, JitInstance& jitInstance) { - int keyLen = MultiByteToWideChar(CP_UTF8, 0, key, -1, nullptr, 0); - if (keyLen == 0) - { - return nullptr; - } + size_t keyLength = strlen(key) + 1; + size_t keyLen = minipal_get_length_utf8_to_utf16(key, keyLength, 0); WCHAR* keyUtf8 = new WCHAR[keyLen]; - if (MultiByteToWideChar(CP_UTF8, 0, key, -1, keyUtf8, keyLen) == 0) - { - delete[] keyUtf8; - return nullptr; - } + minipal_convert_utf8_to_utf16(key, keyLength, (CHAR16_T*)keyUtf8, keyLen, 0); WCHAR* result = GetPrefixedEnvironmentVariable(DOTNET_PREFIX, LEN_OF_DOTNET_PREFIX, keyUtf8, jitInstance); if (result == nullptr) @@ -72,21 +66,11 @@ char* GetConfigFromEnvironmentVariable(const char* key, JitInstance& jitInstance return nullptr; } - int resultLen = WideCharToMultiByte(CP_UTF8, 0, result, -1, nullptr, 0, nullptr, nullptr); - if (resultLen == 0) - { - jitInstance.freeLongLivedArray(result); - return nullptr; - } - - char* resultUtf8 = (char*)jitInstance.allocateLongLivedArray((size_t)resultLen); + size_t resultLength = u16_strlen(result) + 1; + size_t resultLen = minipal_get_length_utf16_to_utf8((const CHAR16_T*)result, resultLength, 0); - if (WideCharToMultiByte(CP_UTF8, 0, result, -1, resultUtf8, resultLen, nullptr, nullptr) == 0) - { - jitInstance.freeLongLivedArray(result); - jitInstance.freeLongLivedArray(resultUtf8); - return nullptr; - } + char* resultUtf8 = (char*)jitInstance.allocateLongLivedArray(resultLen); + minipal_convert_utf16_to_utf8((const CHAR16_T*)result, resultLength, resultUtf8, resultLen, 0); jitInstance.freeLongLivedArray(result); diff --git a/src/coreclr/utilcode/fstring.cpp b/src/coreclr/utilcode/fstring.cpp index 6b4c7988a207ee..3abe6936657533 100644 --- a/src/coreclr/utilcode/fstring.cpp +++ b/src/coreclr/utilcode/fstring.cpp @@ -63,22 +63,16 @@ HRESULT Unicode_Utf8_Length(_In_z_ LPCWSTR pString, _Out_ bool * pAllAscii, _Out * pLength = (DWORD) (p - pString); } - else // use WideCharToMultiByte to calculate result length + else { - * pLength = WideCharToMultiByte(CP_UTF8, 0, pString, -1, NULL, 0, NULL, NULL); + size_t length = minipal_get_length_utf16_to_utf8((const CHAR16_T*)pString, u16_strlen(pString), 0); - if (*pLength == 0) - { - return HRESULT_FROM_GetLastError(); - } - - // Remove the count of null terminator, to be consistent with the all-ASCII case. - --*pLength; - - if (*pLength > MAX_LENGTH) + if (length > MAX_LENGTH) { return COR_E_OVERFLOW; } + + * pLength = (DWORD)length; } return S_OK; @@ -131,11 +125,9 @@ HRESULT Unicode_Utf8(_In_z_ LPCWSTR pString, bool allAscii, _Out_writes_bytes_(l } else { - length = WideCharToMultiByte(CP_UTF8, 0, pString, -1, pBuffer, (int) length + 1, NULL, NULL); - - if (length == 0) + if (minipal_convert_utf16_to_utf8((const CHAR16_T*)pString, u16_strlen(pString), pBuffer, length, 0) == 0) { - return HRESULT_FROM_GetLastError(); + return HRESULT_FROM_WIN32(errno); } } @@ -185,20 +177,14 @@ HRESULT Utf8_Unicode_Length(_In_z_ LPCSTR pString, _Out_ bool * pAllAscii, _Out_ } else { - * pLength = MultiByteToWideChar(CP_UTF8, 0, pString, -1, NULL, 0); + size_t length = minipal_get_length_utf8_to_utf16(pString, strlen(pString), 0); - if (* pLength == 0) - { - return HRESULT_FROM_GetLastError(); - } - - // Remove the count of null terminator, to be consistent with the all-ASCII case. - --*pLength; - - if (* pLength > MAX_LENGTH) + if (length > MAX_LENGTH) { return COR_E_OVERFLOW; } + + * pLength = (DWORD)length; } return S_OK; @@ -252,11 +238,9 @@ HRESULT Utf8_Unicode(_In_z_ LPCSTR pString, bool allAscii, _Out_writes_bytes_(le } else { - length = MultiByteToWideChar(CP_UTF8, 0, pString, -1, pBuffer, (int) length + 1); - - if (length == 0) + if (minipal_convert_utf8_to_utf16(pString, strlen(pString), (CHAR16_T*)pBuffer, length, 0) == 0) { - return HRESULT_FROM_GetLastError(); + return HRESULT_FROM_WIN32(errno); } } diff --git a/src/coreclr/utilcode/sstring.cpp b/src/coreclr/utilcode/sstring.cpp index 276615aa22f581..979de9bf891ea4 100644 --- a/src/coreclr/utilcode/sstring.cpp +++ b/src/coreclr/utilcode/sstring.cpp @@ -750,8 +750,6 @@ void SString::ConvertToUnicode(SString &s) const } CONTRACTL_END; - int page = 0; - switch (GetRepresentation()) { case REPRESENTATION_EMPTY: @@ -765,7 +763,6 @@ void SString::ConvertToUnicode(SString &s) const return; case REPRESENTATION_UTF8: - page = CP_UTF8; break; case REPRESENTATION_ASCII: @@ -777,15 +774,12 @@ void SString::ConvertToUnicode(SString &s) const UNREACHABLE(); } - COUNT_T length = MultiByteToWideChar(page, 0, GetRawANSI(), GetRawCount()+1, 0, 0); - if (length == 0) - ThrowLastError(); + COUNT_T length = (COUNT_T)minipal_get_length_utf8_to_utf16(GetRawUTF8(), GetRawCount() + 1, 0); - s.Resize(length-1, REPRESENTATION_UNICODE); + s.Resize(length - 1, REPRESENTATION_UNICODE); - length = MultiByteToWideChar(page, 0, GetRawANSI(), GetRawCount()+1, s.GetRawUnicode(), length); - if (length == 0) - ThrowLastError(); + if (minipal_convert_utf8_to_utf16(GetRawUTF8(), GetRawCount() + 1, (CHAR16_T*)s.GetRawUnicode(), length, 0) == 0) + ThrowWin32(errno); _ASSERTE(s.IsRepresentation(REPRESENTATION_UNICODE)); } @@ -2218,7 +2212,6 @@ bool SString::DacGetUnicode(COUNT_T cBufChars, SUPPORTS_DAC; PVOID pContent = NULL; - int iPage = CP_ACP; if (IsEmpty() || (GetRepresentation() == REPRESENTATION_EMPTY)) { @@ -2265,22 +2258,23 @@ bool SString::DacGetUnicode(COUNT_T cBufChars, return true; case REPRESENTATION_UTF8: - iPage = CP_UTF8; - FALLTHROUGH; case REPRESENTATION_ASCII: - // iPage defaults to CP_ACP. + { + PSTR pString = reinterpret_cast(pContent); + size_t length = strlen(pString) + 1; if (pcNeedChars) { - *pcNeedChars = MultiByteToWideChar(iPage, 0, reinterpret_cast(pContent), -1, NULL, 0); + *pcNeedChars = (COUNT_T)minipal_get_length_utf8_to_utf16(pString, length, 0); } if (pBuffer && cBufChars) { - if (!MultiByteToWideChar(iPage, 0, reinterpret_cast(pContent), -1, pBuffer, cBufChars)) + if (minipal_convert_utf8_to_utf16(pString, length, (CHAR16_T*)pBuffer, cBufChars, 0) == 0) { return false; } } return true; + } default: DacNotImpl(); diff --git a/src/coreclr/utilcode/stacktrace.cpp b/src/coreclr/utilcode/stacktrace.cpp index 3503b413b64e55..dd2f07c0799fd6 100644 --- a/src/coreclr/utilcode/stacktrace.cpp +++ b/src/coreclr/utilcode/stacktrace.cpp @@ -341,13 +341,14 @@ LPSTR FillSymbolSearchPathThrows(CQuickBytes &qb) #endif // Now we have a working buffer with a bunch of interesting stuff. Time - // to convert it back to ansi for the imagehlp api's. Allocate the buffer - // 2x bigger to handle worst case for MBCS. - ch = ::WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, rcBuff, -1, 0, 0, 0, 0); + // to convert it to UTF-8 for the imagehlp api's. + LPCWSTR wszBuff = rcBuff.GetUnicode(); + size_t cchBuff = u16_strlen(wszBuff) + 1; + ch = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)wszBuff, cchBuff, 0); LPSTR szRtn = (LPSTR) qb.AllocNoThrow(ch + 1); if (!szRtn) return NULL; - WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, rcBuff, -1, szRtn, ch+1, 0, 0); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wszBuff, cchBuff, szRtn, ch + 1, 0); return (szRtn); } LPSTR FillSymbolSearchPath(CQuickBytes &qb) diff --git a/src/coreclr/utilcode/util.cpp b/src/coreclr/utilcode/util.cpp index 32207dc716a842..edfe522e0261f7 100644 --- a/src/coreclr/utilcode/util.cpp +++ b/src/coreclr/utilcode/util.cpp @@ -1645,11 +1645,12 @@ HRESULT Utf2Quick( _ASSERTE_MSG(false, "Integer overflow/underflow"); return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); } - iReqLen = MultiByteToWideChar(CP_UTF8, 0, pStr, -1, rNewStr, (int)(cchAvail.Value())); + size_t cchSrc = strlen(pStr) + 1; + iReqLen = (int)minipal_convert_utf8_to_utf16(pStr, cchSrc, (CHAR16_T*)rNewStr, cchAvail.Value(), 0); // If the buffer was too small, determine what is required. if (iReqLen == 0) - bAlloc = iReqLen = MultiByteToWideChar(CP_UTF8, 0, pStr, -1, 0, 0); + bAlloc = iReqLen = (int)minipal_get_length_utf8_to_utf16(pStr, cchSrc, 0); // Resize the buffer. If the buffer was large enough, this just sets the internal // counter, but if it was too small, this will attempt a reallocation. Note that // the length includes the terminating W('/0'). @@ -1672,7 +1673,7 @@ HRESULT Utf2Quick( _ASSERTE_MSG(false, "Integer overflow/underflow"); return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); } - iActLen = MultiByteToWideChar(CP_UTF8, 0, pStr, -1, rNewStr, (int)(cchAvail.Value())); + iActLen = (int)minipal_convert_utf8_to_utf16(pStr, cchSrc, (CHAR16_T*)rNewStr, cchAvail.Value(), 0); _ASSERTE(iReqLen == iActLen); } ErrExit: diff --git a/src/coreclr/vm/assemblyspec.cpp b/src/coreclr/vm/assemblyspec.cpp index 38d82e2a5c1149..a1c906ef84c29c 100644 --- a/src/coreclr/vm/assemblyspec.cpp +++ b/src/coreclr/vm/assemblyspec.cpp @@ -427,12 +427,11 @@ HRESULT AssemblySpec::EmitToken( AMD.usRevisionNumber = m_context.usRevisionNumber; if (m_context.szLocale) { - AMD.cbLocale = MultiByteToWideChar(CP_UTF8, 0, m_context.szLocale, -1, NULL, 0); - if(AMD.cbLocale==0) - IfFailGo(HRESULT_FROM_GetLastError()); + size_t cchLocale = strlen(m_context.szLocale) + 1; + AMD.cbLocale = (ULONG)minipal_get_length_utf8_to_utf16(m_context.szLocale, cchLocale, 0); AMD.szLocale = (LPWSTR) alloca(AMD.cbLocale * sizeof(WCHAR) ); - if(MultiByteToWideChar(CP_UTF8, 0, m_context.szLocale, -1, AMD.szLocale, AMD.cbLocale)==0) - IfFailGo(HRESULT_FROM_GetLastError()); + if(minipal_convert_utf8_to_utf16(m_context.szLocale, cchLocale, (CHAR16_T*)AMD.szLocale, AMD.cbLocale, 0)==0) + IfFailGo(HRESULT_FROM_WIN32(errno)); } else { AMD.cbLocale = 0; diff --git a/src/coreclr/vm/cdacstress.cpp b/src/coreclr/vm/cdacstress.cpp index ceebbd3aeae559..b36763b2e0b38a 100644 --- a/src/coreclr/vm/cdacstress.cpp +++ b/src/coreclr/vm/cdacstress.cpp @@ -1345,7 +1345,7 @@ static void ResolveMethodNameFromMD(CLRDATA_ADDRESS mdAddr, char* buf, int bufLe unsigned int nameLen = 0; if (SUCCEEDED(s_cdacSosDac->GetMethodDescName(mdAddr, ARRAY_SIZE(wname), wname, &nameLen)) && nameLen > 0) { - WideCharToMultiByte(CP_UTF8, 0, wname, -1, buf, bufLen, NULL, NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wname, u16_strlen(wname) + 1, buf, bufLen, 0); return; } } @@ -2307,7 +2307,7 @@ static void ResolveMethodName(CLRDATA_ADDRESS source, int sourceType, char* buf, unsigned int nameLen = 0; if (SUCCEEDED(pSos->GetMethodDescName(mdAddr, ARRAY_SIZE(wname), wname, &nameLen)) && nameLen > 0) { - WideCharToMultiByte(CP_UTF8, 0, wname, -1, buf, bufLen, NULL, NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wname, u16_strlen(wname) + 1, buf, bufLen, 0); return; } } diff --git a/src/coreclr/vm/commtmemberinfomap.cpp b/src/coreclr/vm/commtmemberinfomap.cpp index 83037b47854413..483206643e3a06 100644 --- a/src/coreclr/vm/commtmemberinfomap.cpp +++ b/src/coreclr/vm/commtmemberinfomap.cpp @@ -744,9 +744,10 @@ void ComMTMemberInfoMap::GetMethodPropsForMeth( if (i < 0) { // Save the name. Have to convert from UTF8. - int iLen = MultiByteToWideChar(CP_UTF8, 0, pPropName, -1, 0, 0); + size_t cchPropName = strlen(pPropName) + 1; + size_t iLen = minipal_get_length_utf8_to_utf16(pPropName, cchPropName, 0); rProps[ix].pName = reinterpret_cast(sNames.Alloc(iLen*sizeof(WCHAR))); - MultiByteToWideChar(CP_UTF8, 0, pPropName, -1, rProps[ix].pName, iLen); + minipal_convert_utf8_to_utf16(pPropName, cchPropName, (CHAR16_T*)rProps[ix].pName, iLen, 0); // Check whether the property has a dispid attribute. hr = pMeth->GetMDImport()->GetDispIdOfMemberDef(pd, &dispid); diff --git a/src/coreclr/vm/dllimport.cpp b/src/coreclr/vm/dllimport.cpp index 6c8f778e0babdc..b435d8bda36239 100644 --- a/src/coreclr/vm/dllimport.cpp +++ b/src/coreclr/vm/dllimport.cpp @@ -5960,7 +5960,8 @@ namespace StackSString ssLibName(SString::Utf8, pMD->GetLibName()); WCHAR wszEPName[50]; - if (MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pMD->GetEntrypointName(), -1, wszEPName, sizeof(wszEPName)/sizeof(WCHAR)) == 0) + LPCSTR szEPName = (LPCSTR)pMD->GetEntrypointName(); + if (minipal_convert_utf8_to_utf16(szEPName, strlen(szEPName) + 1, (CHAR16_T*)wszEPName, ARRAY_SIZE(wszEPName), 0) == 0) { wszEPName[0] = W('?'); wszEPName[1] = W('\0'); diff --git a/src/coreclr/vm/dwbucketmanager.hpp b/src/coreclr/vm/dwbucketmanager.hpp index 6576f6e0600984..d212a5b90ae3b9 100644 --- a/src/coreclr/vm/dwbucketmanager.hpp +++ b/src/coreclr/vm/dwbucketmanager.hpp @@ -545,12 +545,13 @@ void BaseBucketParamsManager::GetModuleName(_Out_writes_(maxLength) WCHAR* targe // Get the assembly name, and determine its length, including terminating NULL. Assembly* pAssembly = pModule->GetAssembly(); LPCUTF8 utf8AssemblyName = pAssembly->GetSimpleName(); - const int assemblyNameLength = MultiByteToWideChar(CP_UTF8, 0, utf8AssemblyName, -1, NULL, 0); + const size_t utf8AssemblyNameLength = strlen(utf8AssemblyName) + 1; + const size_t assemblyNameLength = minipal_get_length_utf8_to_utf16(utf8AssemblyName, utf8AssemblyNameLength, 0); // Allocate a buffer and convert assembly name - multi-module assemblies are no longer supported. - int fullNameLength = assemblyNameLength; + size_t fullNameLength = assemblyNameLength; WCHAR *fullName = reinterpret_cast< WCHAR* >(_alloca(sizeof(WCHAR)*(fullNameLength))); - MultiByteToWideChar(CP_UTF8, 0, utf8AssemblyName, -1, fullName, fullNameLength); + minipal_convert_utf8_to_utf16(utf8AssemblyName, utf8AssemblyNameLength, (CHAR16_T*)fullName, fullNameLength, 0); if (!failed) { diff --git a/src/coreclr/vm/eventtracepriv.h b/src/coreclr/vm/eventtracepriv.h index a1772c8a4fdef6..cbc6da8a59dfba 100644 --- a/src/coreclr/vm/eventtracepriv.h +++ b/src/coreclr/vm/eventtracepriv.h @@ -125,16 +125,15 @@ struct EventStaticEntry LPCUTF8 utf8Name = 0; if (SUCCEEDED(fieldDesc->GetName_NoThrow(&utf8Name))) { - len = MultiByteToWideChar(CP_ACP, 0, utf8Name, -1, name, sizeRemaining - sizeof(EventStaticEntry)); + len = (int)minipal_convert_utf8_to_utf16(utf8Name, strlen(utf8Name) + 1, (CHAR16_T*)name, + (sizeRemaining - sizeof(EventStaticEntry)) / sizeof(WCHAR), 0); if (len <= 0) { - // We will ignore corrupted/bad metadata here and only emit names for fields which are - // up to 255 characters (and also don't fit in the buffer). - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && sizeRemaining < 256) + // We will only emit names for fields which are up to 255 characters (and also don't fit in the buffer). + if (sizeRemaining < 256) return -1; // nothing written, insufficient buffer. Flush and try again. - // If the name is larger than 255 or we have some other error converting the string, - // just emit an empty string. + // If the name is larger than 255, just emit an empty string. len = 1; name[0] = 0; } diff --git a/src/coreclr/vm/gcenv.ee.cpp b/src/coreclr/vm/gcenv.ee.cpp index fda2b1b2875e31..cbda6116a170ac 100644 --- a/src/coreclr/vm/gcenv.ee.cpp +++ b/src/coreclr/vm/gcenv.ee.cpp @@ -1285,7 +1285,7 @@ bool GCToEEInterface::GetBooleanConfigValue(const char* privateKey, const char* } WCHAR configKey[MaxConfigKeyLength]; - if (MultiByteToWideChar(CP_ACP, 0, privateKey, -1 /* key is null-terminated */, configKey, MaxConfigKeyLength) == 0) + if (minipal_convert_utf8_to_utf16(privateKey, strlen(privateKey) + 1, (CHAR16_T*)configKey, MaxConfigKeyLength, 0) == 0) { // whatever this is... it's not something we care about. (It was too long, wasn't unicode, etc.) return false; @@ -1300,7 +1300,7 @@ bool GCToEEInterface::GetBooleanConfigValue(const char* privateKey, const char* } else if (publicKey != NULL) { - if (MultiByteToWideChar(CP_ACP, 0, publicKey, -1 /* key is null-terminated */, configKey, MaxConfigKeyLength) == 0) + if (minipal_convert_utf8_to_utf16(publicKey, strlen(publicKey) + 1, (CHAR16_T*)configKey, MaxConfigKeyLength, 0) == 0) { // whatever this is... it's not something we care about. (It was too long, wasn't unicode, etc.) return false; @@ -1335,7 +1335,7 @@ bool GCToEEInterface::GetIntConfigValue(const char* privateKey, const char* publ } WCHAR configKey[MaxConfigKeyLength]; - if (MultiByteToWideChar(CP_ACP, 0, privateKey, -1 /* key is null-terminated */, configKey, MaxConfigKeyLength) == 0) + if (minipal_convert_utf8_to_utf16(privateKey, strlen(privateKey) + 1, (CHAR16_T*)configKey, MaxConfigKeyLength, 0) == 0) { // whatever this is... it's not something we care about. (It was too long, wasn't unicode, etc.) return false; @@ -1372,7 +1372,7 @@ bool GCToEEInterface::GetIntConfigValue(const char* privateKey, const char* publ } else if (publicKey != NULL) { - if (MultiByteToWideChar(CP_ACP, 0, publicKey, -1 /* key is null-terminated */, configKey, MaxConfigKeyLength) == 0) + if (minipal_convert_utf8_to_utf16(publicKey, strlen(publicKey) + 1, (CHAR16_T*)configKey, MaxConfigKeyLength, 0) == 0) { // whatever this is... it's not something we care about. (It was too long, wasn't unicode, etc.) return false; @@ -1395,7 +1395,7 @@ bool GCToEEInterface::GetStringConfigValue(const char* privateKey, const char* p } CONTRACTL_END; WCHAR configKey[MaxConfigKeyLength]; - if (MultiByteToWideChar(CP_ACP, 0, privateKey, -1 /* key is null-terminated */, configKey, MaxConfigKeyLength) == 0) + if (minipal_convert_utf8_to_utf16(privateKey, strlen(privateKey) + 1, (CHAR16_T*)configKey, MaxConfigKeyLength, 0) == 0) { // whatever this is... it's not something we care about. (It was too long, wasn't unicode, etc.) return false; @@ -1408,7 +1408,7 @@ bool GCToEEInterface::GetStringConfigValue(const char* privateKey, const char* p { if (publicKey != NULL) { - if (MultiByteToWideChar(CP_ACP, 0, publicKey, -1 /* key is null-terminated */, configKey, MaxConfigKeyLength) == 0) + if (minipal_convert_utf8_to_utf16(publicKey, strlen(publicKey) + 1, (CHAR16_T*)configKey, MaxConfigKeyLength, 0) == 0) { // whatever this is... it's not something we care about. (It was too long, wasn't unicode, etc.) return false; @@ -1421,7 +1421,8 @@ bool GCToEEInterface::GetStringConfigValue(const char* privateKey, const char* p } } - int charCount = WideCharToMultiByte(CP_ACP, 0, out, -1 /* out is null-terminated */, NULL, 0, nullptr, nullptr); + size_t cchOut = u16_strlen(out) + 1; + int charCount = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)out, cchOut, 0); if (charCount == 0) { // this should only happen if the config subsystem gives us a string that's not valid @@ -1444,10 +1445,9 @@ bool GCToEEInterface::GetStringConfigValue(const char* privateKey, const char* p return false; } - if (WideCharToMultiByte(CP_ACP, 0, out, -1 /* out is null-terminated */, - configResult.GetValue(), charCount, nullptr, nullptr) == 0) + if (minipal_convert_utf16_to_utf8((const CHAR16_T*)out, cchOut, configResult.GetValue(), charCount, 0) == 0) { - // this should never happen, the previous call to WideCharToMultiByte that computed the charCount should + // this should never happen, the previous call that computed the charCount should // have caught all issues. assert(false); if (fromClrConfig) diff --git a/src/coreclr/vm/gctoclreventsink.cpp b/src/coreclr/vm/gctoclreventsink.cpp index 13e35e861223c9..446441bc07fcb2 100644 --- a/src/coreclr/vm/gctoclreventsink.cpp +++ b/src/coreclr/vm/gctoclreventsink.cpp @@ -14,7 +14,7 @@ void GCToCLREventSink::FireDynamicEvent(const char* eventName, void* payload, ui const size_t EventNameMaxSize = 255; WCHAR wideEventName[EventNameMaxSize]; - if (MultiByteToWideChar(CP_ACP, 0, eventName, -1, wideEventName, EventNameMaxSize) == 0) + if (minipal_convert_utf8_to_utf16(eventName, strlen(eventName) + 1, (CHAR16_T*)wideEventName, EventNameMaxSize, 0) == 0) { return; } diff --git a/src/coreclr/vm/gdbjit.cpp b/src/coreclr/vm/gdbjit.cpp index 45836c553984d0..7916f7131b67d7 100644 --- a/src/coreclr/vm/gdbjit.cpp +++ b/src/coreclr/vm/gdbjit.cpp @@ -520,11 +520,12 @@ GetDebugInfoFromPDB(MethodDesc* methodDescPtr, for (int i = 0; i < locals.size; i++) { - size_t sizeRequired = WideCharToMultiByte(CP_UTF8, 0, methodDebugInfo.locals[i].name, -1, NULL, 0, NULL, NULL); + const CHAR16_T* localName = (const CHAR16_T*)methodDebugInfo.locals[i].name; + size_t cchLocalName = u16_strlen(methodDebugInfo.locals[i].name) + 1; + size_t sizeRequired = minipal_get_length_utf16_to_utf8(localName, cchLocalName, 0); locals.localsName[i] = new char[sizeRequired]; - int len = WideCharToMultiByte( - CP_UTF8, 0, methodDebugInfo.locals[i].name, -1, locals.localsName[i], sizeRequired, NULL, NULL); + minipal_convert_utf16_to_utf8(localName, cchLocalName, locals.localsName[i], sizeRequired, 0); locals.localsScope[i].ilStartOffset = methodDebugInfo.locals[i].startOffset; locals.localsScope[i].ilEndOffset = methodDebugInfo.locals[i].endOffset; } @@ -552,7 +553,7 @@ GetDebugInfoFromPDB(MethodDesc* methodDescPtr, if ((ULONG)(methodDebugInfo.points[i].ilOffset) == map[j].ilOffset) { s.fileIndex = 0; - int len = WideCharToMultiByte(CP_UTF8, 0, sp.fileName, -1, s.fileName, sizeof(s.fileName), NULL, NULL); + size_t len = minipal_convert_utf16_to_utf8((const CHAR16_T*)sp.fileName, u16_strlen(sp.fileName), s.fileName, sizeof(s.fileName) - 1, 0); s.fileName[len] = 0; s.lineNumber = sp.lineNumber; break; @@ -2524,11 +2525,10 @@ void NotifyGdb::OnMethodPrepared(MethodDesc* methodDescPtr, PCODE pCode, const C const char* szModName = modName.GetUTF8(); const char* szModuleFile = SplitFilename(szModName); - int length = MultiByteToWideChar(CP_UTF8, 0, szModuleFile, -1, NULL, 0); - if (length == 0) - return; + size_t cchModuleFile = strlen(szModuleFile) + 1; + size_t length = minipal_get_length_utf8_to_utf16(szModuleFile, cchModuleFile, 0); NewArrayHolder wszModuleFile = new WCHAR[length+1]; - length = MultiByteToWideChar(CP_UTF8, 0, szModuleFile, -1, wszModuleFile, length); + length = minipal_convert_utf8_to_utf16(szModuleFile, cchModuleFile, (CHAR16_T*)wszModuleFile.GetValue(), length, 0); if (length == 0) return; diff --git a/src/coreclr/vm/interoputil.cpp b/src/coreclr/vm/interoputil.cpp index ac1f1eac682d5e..d0b5f1fdb5224e 100644 --- a/src/coreclr/vm/interoputil.cpp +++ b/src/coreclr/vm/interoputil.cpp @@ -621,7 +621,7 @@ HRESULT GetStringizedTypeLibGuidForAssembly(Assembly *pAssembly, CQuickArrayGetSimpleName(); cbName=(ULONG)strlen(pszName); - cchName = MultiByteToWideChar(CP_ACP,0, pszName,cbName+1, 0,0); + cchName = (ULONG)minipal_get_length_utf8_to_utf16(pszName, cbName+1, 0); // See if there is a public key. EX_TRY @@ -686,7 +686,7 @@ HRESULT GetStringizedTypeLibGuidForAssembly(Assembly *pAssembly, CQuickArray(buffer.AllocThrows(byteCount)); - if (WideCharToMultiByte(codePage, 0, pwzString, -1, pStr, byteCount, nullptr, nullptr) == 0) - { - ThrowWin32(ERROR_NO_UNICODE_TRANSLATION); - } + minipal_convert_utf16_to_utf8((const CHAR16_T*)pwzString, cchString, pStr, byteCount, 0); PrintToStdErrA(pStr); } diff --git a/src/native/minipal/utf8.h b/src/native/minipal/utf8.h index 009f0f0c1712a9..c074eda26685f8 100644 --- a/src/native/minipal/utf8.h +++ b/src/native/minipal/utf8.h @@ -24,7 +24,8 @@ extern "C" * @param source The source string in UTF-8 format. * @param sourceLength Length of the source string. * @param flags Flags to alter the behavior of converter. Supported flags are MINIPAL_MB_NO_REPLACE_INVALID_CHARS and MINIPAL_TREAT_AS_LITTLE_ENDIAN. - * @return Length of UTF-16 buffer required by the conversion. + * @return Length of UTF-16 buffer required by the conversion, or 0 with errno set to MINIPAL_ERROR_NO_UNICODE_TRANSLATION + * if MINIPAL_MB_NO_REPLACE_INVALID_CHARS is set and the source has an ill-formed sequence. */ size_t minipal_get_length_utf8_to_utf16(const char* source, size_t sourceLength, unsigned int flags); @@ -43,10 +44,11 @@ size_t minipal_get_length_utf16_to_utf8(const CHAR16_T* source, size_t sourceLen * * @param source The source string in UTF-8 format. * @param sourceLength Length of the source string. - * @param destination Pointer to the destination UTF-16 string. It can be NULL to query number of items required by the conversion. + * @param destination Pointer to the destination UTF-16 string. Use minipal_get_length_utf8_to_utf16 for the number of items required. * @param destinationLength Length of the destination string. * @param flags Flags to alter the behavior of converter. Supported flags are MINIPAL_MB_NO_REPLACE_INVALID_CHARS and MINIPAL_TREAT_AS_LITTLE_ENDIAN. - * @return Number of items written by the conversion. + * @return Number of items written by the conversion, or 0 with errno set to MINIPAL_ERROR_INSUFFICIENT_BUFFER or + * MINIPAL_ERROR_NO_UNICODE_TRANSLATION if it fails. errno is 0 when the conversion succeeds. */ size_t minipal_convert_utf8_to_utf16(const char* source, size_t sourceLength, CHAR16_T* destination, size_t destinationLength, unsigned int flags); @@ -55,10 +57,11 @@ size_t minipal_convert_utf8_to_utf16(const char* source, size_t sourceLength, CH * * @param source The source string in UTF-16 format. * @param sourceLength Length of the source string. - * @param destination Pointer to the destination UTF-8 string. It can be NULL to query number of items required by the conversion. + * @param destination Pointer to the destination UTF-8 string. Use minipal_get_length_utf16_to_utf8 for the number of items required. * @param destinationLength Length of the destination string. * @param flags Flags to alter the behavior of converter. Supported flags are MINIPAL_MB_NO_REPLACE_INVALID_CHARS and MINIPAL_TREAT_AS_LITTLE_ENDIAN. - * @return Number of items written by the conversion. + * @return Number of items written by the conversion, or 0 with errno set to MINIPAL_ERROR_INSUFFICIENT_BUFFER if it fails. + * errno is 0 when the conversion succeeds. */ size_t minipal_convert_utf16_to_utf8(const CHAR16_T* source, size_t sourceLength, char* destination, size_t destinationLength, unsigned int flags); From c415d708eff07d4d8b1fa1099b435daf75c3343c Mon Sep 17 00:00:00 2001 From: am11 <3840695+am11@users.noreply.github.com> Date: Wed, 4 Nov 2026 19:53:44 +0200 Subject: [PATCH 03/13] Delete the PAL MultiByteToWideChar and WideCharToMultiByte Nothing calls them anymore, so remove unicode.cpp along with GetConsoleOutputCP, which only ever returned CP_UTF8 on Unix, and the UNICODE debug channel. Remove their declarations and the code page structures and flags that only they used from pal.h, the DAC exports, and the PAL locale tests, which the native minipal tests in src/tests replace. --- .../dlls/mscordac/mscordac_unixexports.src | 2 - src/coreclr/pal/inc/pal.h | 43 --- src/coreclr/pal/src/CMakeLists.txt | 1 - src/coreclr/pal/src/cruntime/wchar.cpp | 12 +- src/coreclr/pal/src/file/directory.cpp | 8 +- src/coreclr/pal/src/file/file.cpp | 2 +- src/coreclr/pal/src/file/path.cpp | 2 +- src/coreclr/pal/src/include/pal/dbgmsg.h | 2 - src/coreclr/pal/src/init/pal.cpp | 4 +- src/coreclr/pal/src/loader/module.cpp | 2 +- src/coreclr/pal/src/locale/unicode.cpp | 222 -------------- src/coreclr/pal/src/misc/dbgmsg.cpp | 1 - src/coreclr/pal/src/misc/environ.cpp | 12 +- src/coreclr/pal/tests/palsuite/CMakeLists.txt | 9 - .../pal/tests/palsuite/compilableTests.txt | 9 - .../MultiByteToWideChar/test1/test1.cpp | 80 ----- .../MultiByteToWideChar/test2/test2.cpp | 67 ----- .../MultiByteToWideChar/test3/test3.cpp | 72 ----- .../MultiByteToWideChar/test4/test4.cpp | 282 ------------------ .../WideCharToMultiByte/test1/test1.cpp | 101 ------- .../WideCharToMultiByte/test2/test2.cpp | 87 ------ .../WideCharToMultiByte/test3/test3.cpp | 99 ------ .../WideCharToMultiByte/test4/test4.cpp | 130 -------- .../WideCharToMultiByte/test5/test5.cpp | 261 ---------------- .../pal/tests/palsuite/paltestlist.txt | 8 - .../palsuite/paltestlist_to_be_reviewed.txt | 1 - 26 files changed, 21 insertions(+), 1498 deletions(-) delete mode 100644 src/coreclr/pal/src/locale/unicode.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/test2.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/test3.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/test4.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.cpp diff --git a/src/coreclr/dlls/mscordac/mscordac_unixexports.src b/src/coreclr/dlls/mscordac/mscordac_unixexports.src index 55a97b0fcb8222..2a68e421a06e9e 100644 --- a/src/coreclr/dlls/mscordac/mscordac_unixexports.src +++ b/src/coreclr/dlls/mscordac/mscordac_unixexports.src @@ -86,7 +86,6 @@ nativeStringResourceTable_mscorrc #LoadLibraryExW #MapViewOfFile #MapViewOfFileEx -#MultiByteToWideChar #OutputDebugStringW #OutputDebugStringA #RaiseException @@ -100,7 +99,6 @@ nativeStringResourceTable_mscorrc #SwitchToThread #TerminateProcess #UnmapViewOfFile -#WideCharToMultiByte #WriteFile #GUID_NULL diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 3d9d91e74689e4..a4e23aeaaeaf82 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -529,11 +529,6 @@ PALAPI FlushFileBuffers( IN HANDLE hFile); -PALIMPORT -UINT -PALAPI -GetConsoleOutputCP(); - PALIMPORT DWORD PALAPI @@ -2286,44 +2281,6 @@ FlushInstructionCache( IN LPCVOID lpBaseAddress, IN SIZE_T dwSize); -#define MAX_LEADBYTES 12 -#define MAX_DEFAULTCHAR 2 - -typedef struct _cpinfo { - UINT MaxCharSize; - BYTE DefaultChar[MAX_DEFAULTCHAR]; - BYTE LeadByte[MAX_LEADBYTES]; -} CPINFO, *LPCPINFO; - -#define MB_PRECOMPOSED 0x00000001 -#define MB_ERR_INVALID_CHARS 0x00000008 - -PALIMPORT -int -PALAPI -MultiByteToWideChar( - IN UINT CodePage, - IN DWORD dwFlags, - IN LPCSTR lpMultiByteStr, - IN int cbMultiByte, - OUT LPWSTR lpWideCharStr, - IN int cchWideChar); - -#define WC_NO_BEST_FIT_CHARS 0x00000400 - -PALIMPORT -int -PALAPI -WideCharToMultiByte( - IN UINT CodePage, - IN DWORD dwFlags, - IN LPCWSTR lpWideCharStr, - IN int cchWideChar, - OUT LPSTR lpMultiByteStr, - IN int cbMultyByte, - IN LPCSTR lpDefaultChar, - OUT LPBOOL lpUsedDefaultChar); - #define EXCEPTION_NONCONTINUABLE 0x1 #define EXCEPTION_UNWINDING 0x2 diff --git a/src/coreclr/pal/src/CMakeLists.txt b/src/coreclr/pal/src/CMakeLists.txt index 73cdefc3844afa..48380fe2d43333 100644 --- a/src/coreclr/pal/src/CMakeLists.txt +++ b/src/coreclr/pal/src/CMakeLists.txt @@ -159,7 +159,6 @@ set(SOURCES init/pal.cpp init/sxs.cpp loader/module.cpp - locale/unicode.cpp map/map.cpp misc/cgroup.cpp misc/dbgmsg.cpp diff --git a/src/coreclr/pal/src/cruntime/wchar.cpp b/src/coreclr/pal/src/cruntime/wchar.cpp index aad962fb2b490a..7c889685d33b3e 100644 --- a/src/coreclr/pal/src/cruntime/wchar.cpp +++ b/src/coreclr/pal/src/cruntime/wchar.cpp @@ -47,7 +47,7 @@ _wtoi( len = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)string, PAL_wcslen(string) + 1, 0); if (!len) { - ASSERT("WideCharToMultiByte failed. Error is %d\n", + ASSERT("UTF-16 to UTF-8 conversion failed. Error is %d\n", GetLastError()); return -1; } @@ -61,7 +61,7 @@ _wtoi( len = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)string, PAL_wcslen(string) + 1, tempStr, len, 0); if (!len) { - ASSERT("WideCharToMultiByte failed. Error is %d\n", + ASSERT("UTF-16 to UTF-8 conversion failed. Error is %d\n", GetLastError()); free(tempStr); return -1; @@ -252,7 +252,7 @@ PAL_wcstoul( if (!size) { dwLastError = GetLastError(); - ASSERT("WideCharToMultiByte failed. Error is %d\n", dwLastError); + ASSERT("UTF-16 to UTF-8 conversion failed. Error is %d\n", dwLastError); SetLastError(ERROR_INVALID_PARAMETER); res = 0; goto PAL_wcstoulExit; @@ -269,7 +269,7 @@ PAL_wcstoul( if (!size) { dwLastError = GetLastError(); - ASSERT("WideCharToMultiByte failed. Error is %d\n", dwLastError); + ASSERT("UTF-16 to UTF-8 conversion failed. Error is %d\n", dwLastError); SetLastError(ERROR_INVALID_PARAMETER); res = 0; goto PAL_wcstoulExit; @@ -342,7 +342,7 @@ PAL__wcstoui64( if (!size) { dwLastError = GetLastError(); - ASSERT("WideCharToMultiByte failed. Error is %d\n", dwLastError); + ASSERT("UTF-16 to UTF-8 conversion failed. Error is %d\n", dwLastError); SetLastError(ERROR_INVALID_PARAMETER); res = 0; goto PAL__wcstoui64Exit; @@ -359,7 +359,7 @@ PAL__wcstoui64( if (!size) { dwLastError = GetLastError(); - ASSERT("WideCharToMultiByte failed. Error is %d\n", dwLastError); + ASSERT("UTF-16 to UTF-8 conversion failed. Error is %d\n", dwLastError); SetLastError(ERROR_INVALID_PARAMETER); res = 0; goto PAL__wcstoui64Exit; diff --git a/src/coreclr/pal/src/file/directory.cpp b/src/coreclr/pal/src/file/directory.cpp index 482b4a0d7077e4..998cd69985d3f8 100644 --- a/src/coreclr/pal/src/file/directory.cpp +++ b/src/coreclr/pal/src/file/directory.cpp @@ -70,7 +70,7 @@ CreateDirectoryW( /* translate the wide char lpPathName string to multibyte string */ if(0 == (mb_size = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpPathName, PAL_wcslen(lpPathName) + 1, 0))) { - ASSERT("WideCharToMultiByte failure! error is %d\n", GetLastError()); + ASSERT("UTF-16 to UTF-8 conversion failure! error is %d\n", GetLastError()); dwLastError = ERROR_INTERNAL_ERROR; goto done; } @@ -78,7 +78,7 @@ CreateDirectoryW( if (((mb_dir = (char *)malloc(mb_size)) == NULL) || ((int)minipal_convert_utf16_to_utf8((const CHAR16_T*)lpPathName, PAL_wcslen(lpPathName) + 1, mb_dir, mb_size, 0) != mb_size)) { - ASSERT("WideCharToMultiByte or malloc failure! LastError:%d errno:%d\n", + ASSERT("UTF-16 to UTF-8 conversion or malloc failure! LastError:%d errno:%d\n", GetLastError(), errno); dwLastError = ERROR_INTERNAL_ERROR; goto done; @@ -212,7 +212,7 @@ RemoveDirectoryW( if( mb_size == 0 ) { mb_dirPathString.CloseBuffer(0); - ASSERT("WideCharToMultiByte failure! error is %d\n", dwLastError); + ASSERT("UTF-16 to UTF-8 conversion failure! error is %d\n", dwLastError); dwLastError = ERROR_INTERNAL_ERROR; goto done; } @@ -339,7 +339,7 @@ SetCurrentDirectoryW( { dirPathString.CloseBuffer(0); dwLastError = GetLastError(); - ASSERT("WideCharToMultiByte failure! error is %d\n", dwLastError); + ASSERT("UTF-16 to UTF-8 conversion failure! error is %d\n", dwLastError); dwLastError = ERROR_INTERNAL_ERROR; bRet = FALSE; goto done; diff --git a/src/coreclr/pal/src/file/file.cpp b/src/coreclr/pal/src/file/file.cpp index ceb75c5913db03..7f1a8da17ea05c 100644 --- a/src/coreclr/pal/src/file/file.cpp +++ b/src/coreclr/pal/src/file/file.cpp @@ -846,7 +846,7 @@ CreateFileW( { namePathString.CloseBuffer(0); DWORD dwLastError = GetLastError(); - ASSERT("WideCharToMultiByte failure! error is %d\n", dwLastError); + ASSERT("UTF-16 to UTF-8 conversion failure! error is %d\n", dwLastError); palError = ERROR_INTERNAL_ERROR; goto done; } diff --git a/src/coreclr/pal/src/file/path.cpp b/src/coreclr/pal/src/file/path.cpp index d5dbfeaae77d9f..9f3ad5f914b831 100644 --- a/src/coreclr/pal/src/file/path.cpp +++ b/src/coreclr/pal/src/file/path.cpp @@ -196,7 +196,7 @@ GetFullPathNameW( if( srcSize == 0 ) { DWORD dwLastError = GetLastError(); - ASSERT("WideCharToMultiByte failure! error is %d\n", dwLastError); + ASSERT("UTF-16 to UTF-8 conversion failure! error is %d\n", dwLastError); SetLastError(ERROR_INVALID_PARAMETER); goto done; } diff --git a/src/coreclr/pal/src/include/pal/dbgmsg.h b/src/coreclr/pal/src/include/pal/dbgmsg.h index 4103f2c54c8529..18b43e4152d31a 100644 --- a/src/coreclr/pal/src/include/pal/dbgmsg.h +++ b/src/coreclr/pal/src/include/pal/dbgmsg.h @@ -51,7 +51,6 @@ Available channels : THREAD : Threading mechanism EXCEPT : Structured Exception Handling functions CRT : PAL implementation of the C Runtime Library functions - UNICODE : Unicode support API ARCH : platform-dependent stuff SYNC : Management of synchronization objects FILE : File I/O API @@ -166,7 +165,6 @@ typedef enum DCI_THREAD, DCI_EXCEPT, DCI_CRT, - DCI_UNICODE, DCI_ARCH, DCI_SYNC, DCI_FILE, diff --git a/src/coreclr/pal/src/init/pal.cpp b/src/coreclr/pal/src/init/pal.cpp index 0875b3a9656ddd..93de656ed55a6d 100644 --- a/src/coreclr/pal/src/init/pal.cpp +++ b/src/coreclr/pal/src/init/pal.cpp @@ -733,7 +733,7 @@ static LPWSTR INIT_GetCurrentEXEPath() return_size = (INT)minipal_get_length_utf8_to_utf16(real_path, strlen(real_path) + 1, 0); if (0 == return_size) { - ASSERT("MultiByteToWideChar failure\n"); + ASSERT("UTF-8 to UTF-16 conversion failure\n"); return nullptr; } @@ -747,7 +747,7 @@ static LPWSTR INIT_GetCurrentEXEPath() { if (!minipal_convert_utf8_to_utf16(real_path, strlen(real_path) + 1, (CHAR16_T*)return_value, return_size, 0)) { - ASSERT("MultiByteToWideChar failure\n"); + ASSERT("UTF-8 to UTF-16 conversion failure\n"); free(return_value); return_value = nullptr; } diff --git a/src/coreclr/pal/src/loader/module.cpp b/src/coreclr/pal/src/loader/module.cpp index 334b9e0fc09844..1aa0af6490f503 100644 --- a/src/coreclr/pal/src/loader/module.cpp +++ b/src/coreclr/pal/src/loader/module.cpp @@ -1301,7 +1301,7 @@ static bool LOADConvertLibraryPathWideStringToMultibyteString( { DWORD dwLastError = GetLastError(); - ASSERT("WideCharToMultiByte failure! error is %d\n", dwLastError); + ASSERT("UTF-16 to UTF-8 conversion failure! error is %d\n", dwLastError); SetLastError(ERROR_INVALID_PARAMETER); return false; diff --git a/src/coreclr/pal/src/locale/unicode.cpp b/src/coreclr/pal/src/locale/unicode.cpp deleted file mode 100644 index a66a0edc14d488..00000000000000 --- a/src/coreclr/pal/src/locale/unicode.cpp +++ /dev/null @@ -1,222 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*++ -Module Name: -unicode.cpp - -Abstract: -Implementation of all functions related to Unicode support ---*/ - -#include "pal/thread.hpp" - -#include "pal/palinternal.h" -#include "pal/dbgmsg.h" -#include "pal/file.h" -#include -#include -#include "pal/cruntime.h" -#include "pal/stackstring.hpp" - -#include -#include -#include - -#include - -using namespace CorUnix; - -SET_DEFAULT_DEBUG_CHANNEL(UNICODE); - -/*++ -Function: -GetConsoleOutputCP - -See MSDN doc. ---*/ -UINT -PALAPI -GetConsoleOutputCP( - VOID) -{ - return CP_UTF8; -} - -/*++ -Function: -MultiByteToWideChar - -See MSDN doc. - ---*/ -int -PALAPI -MultiByteToWideChar( - IN UINT CodePage, - IN DWORD dwFlags, - IN LPCSTR lpMultiByteStr, - IN int cbMultiByte, - OUT LPWSTR lpWideCharStr, - IN int cchWideChar) -{ - INT retval =0; - - PERF_ENTRY(MultiByteToWideChar); - ENTRY("MultiByteToWideChar(CodePage=%u, dwFlags=%#x, lpMultiByteStr=%p (%s)," - " cbMultiByte=%d, lpWideCharStr=%p, cchWideChar=%d)\n", - CodePage, dwFlags, lpMultiByteStr?lpMultiByteStr:"NULL", lpMultiByteStr?lpMultiByteStr:"NULL", - cbMultiByte, lpWideCharStr, cchWideChar); - - if (dwFlags & ~(MB_ERR_INVALID_CHARS | MB_PRECOMPOSED)) - { - ASSERT("Error dwFlags(0x%x) parameter is invalid\n", dwFlags); - SetLastError(ERROR_INVALID_FLAGS); - goto EXIT; - } - - if ( (cbMultiByte == 0) || (cchWideChar < 0) || - (lpMultiByteStr == NULL) || - ((cchWideChar != 0) && - ((lpWideCharStr == NULL) || - (lpMultiByteStr == (LPSTR)lpWideCharStr))) ) - { - ERROR("Error lpMultiByteStr parameters are invalid\n"); - SetLastError(ERROR_INVALID_PARAMETER); - goto EXIT; - } - - if (CodePage == CP_UTF8 || CodePage == CP_ACP) - { - if (cbMultiByte < 0) - cbMultiByte = strlen(lpMultiByteStr) + 1; - - if (!lpWideCharStr || cchWideChar == 0) - retval = minipal_get_length_utf8_to_utf16(lpMultiByteStr, cbMultiByte, dwFlags); - - if (lpWideCharStr) - { - if (cchWideChar == 0) cchWideChar = retval; - retval = minipal_convert_utf8_to_utf16(lpMultiByteStr, cbMultiByte, (CHAR16_T*)lpWideCharStr, cchWideChar, dwFlags); - } - - goto EXIT; - } - - ERROR( "This code page is not in the system.\n" ); - SetLastError( ERROR_INVALID_PARAMETER ); - goto EXIT; - -EXIT: - - LOGEXIT("MultiByteToWideChar returns %d.\n",retval); - PERF_EXIT(MultiByteToWideChar); - return retval; -} - - -/*++ -Function: -WideCharToMultiByte - -See MSDN doc. - ---*/ -int -PALAPI -WideCharToMultiByte( - IN UINT CodePage, - IN DWORD dwFlags, - IN LPCWSTR lpWideCharStr, - IN int cchWideChar, - OUT LPSTR lpMultiByteStr, - IN int cbMultiByte, - IN LPCSTR lpDefaultChar, - OUT LPBOOL lpUsedDefaultChar) -{ - INT retval =0; - char defaultChar = '?'; - BOOL usedDefaultChar = FALSE; - - PERF_ENTRY(WideCharToMultiByte); - ENTRY("WideCharToMultiByte(CodePage=%u, dwFlags=%#x, lpWideCharStr=%p (%S), " - "cchWideChar=%d, lpMultiByteStr=%p, cbMultiByte=%d, " - "lpDefaultChar=%p, lpUsedDefaultChar=%p)\n", - CodePage, dwFlags, lpWideCharStr?lpWideCharStr:W16_NULLSTRING, lpWideCharStr?lpWideCharStr:W16_NULLSTRING, - cchWideChar, lpMultiByteStr, cbMultiByte, - lpDefaultChar, lpUsedDefaultChar); - - if (dwFlags & ~WC_NO_BEST_FIT_CHARS) - { - ERROR("dwFlags %d invalid\n", dwFlags); - SetLastError(ERROR_INVALID_FLAGS); - goto EXIT; - } - - // No special action is needed for WC_NO_BEST_FIT_CHARS. The default - // behavior of this API on Unix is not to find the best fit for a unicode - // character that does not map directly into a code point in the given - // code page. The best fit functionality is not available in wctomb on Unix - // and is better left unimplemented for security reasons anyway. - - if ((cchWideChar < -1) || (cbMultiByte < 0) || - (lpWideCharStr == NULL) || - ((cbMultiByte != 0) && - ((lpMultiByteStr == NULL) || - (lpWideCharStr == (LPWSTR)lpMultiByteStr))) ) - { - ERROR("Error lpWideCharStr parameters are invalid\n"); - SetLastError(ERROR_INVALID_PARAMETER); - goto EXIT; - } - - if (lpDefaultChar != NULL) - { - defaultChar = *lpDefaultChar; - } - - if (CodePage == CP_UTF8 || CodePage == CP_ACP) - { - if (cchWideChar < 0) - cchWideChar = minipal_u16_strlen((CHAR16_T*)lpWideCharStr) + 1; - - if (!lpMultiByteStr || cbMultiByte == 0) - retval = minipal_get_length_utf16_to_utf8((CHAR16_T*)lpWideCharStr, cchWideChar, dwFlags); - - if (lpMultiByteStr) - { - if (cbMultiByte == 0) cbMultiByte = retval; - retval = minipal_convert_utf16_to_utf8((CHAR16_T*)lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte, dwFlags); - } - - goto EXIT; - } - - ERROR( "This code page is not in the system.\n" ); - SetLastError( ERROR_INVALID_PARAMETER ); - goto EXIT; - -EXIT: - - if ( lpUsedDefaultChar != NULL ) - { - *lpUsedDefaultChar = usedDefaultChar; - } - - /* Flag the cases when WC_NO_BEST_FIT_CHARS was not specified - * but we found characters that had to be replaced with default - * characters. Note that Windows would have attempted to find - * best fit characters under these conditions and that could pose - * a security risk. - */ - _ASSERT_MSG((dwFlags & WC_NO_BEST_FIT_CHARS) || !usedDefaultChar, - "WideCharToMultiByte found a string which doesn't round trip: (%p)%S " - "and WC_NO_BEST_FIT_CHARS was not specified\n", - lpWideCharStr, lpWideCharStr); - - LOGEXIT("WideCharToMultiByte returns INT %d\n", retval); - PERF_EXIT(WideCharToMultiByte); - return retval; -} - -extern char * g_szCoreCLRPath; diff --git a/src/coreclr/pal/src/misc/dbgmsg.cpp b/src/coreclr/pal/src/misc/dbgmsg.cpp index 8ec68fb5530a85..520f22a6e48da4 100644 --- a/src/coreclr/pal/src/misc/dbgmsg.cpp +++ b/src/coreclr/pal/src/misc/dbgmsg.cpp @@ -74,7 +74,6 @@ static const char *dbg_channel_names[]= "THREAD", "EXCEPT", "CRT", - "UNICODE", "ARCH", "SYNC", "FILE", diff --git a/src/coreclr/pal/src/misc/environ.cpp b/src/coreclr/pal/src/misc/environ.cpp index d22bb658e51fe5..957d56c8f5f204 100644 --- a/src/coreclr/pal/src/misc/environ.cpp +++ b/src/coreclr/pal/src/misc/environ.cpp @@ -192,7 +192,7 @@ GetEnvironmentVariableW( if (0 == minipal_convert_utf16_to_utf8((const CHAR16_T*)lpName, PAL_wcslen(lpName) + 1, inBuff, inBuffSize, 0)) { - ASSERT("WideCharToMultiByte failed!\n"); + ASSERT("UTF-16 to UTF-8 conversion failed!\n"); SetLastError(ERROR_INTERNAL_ERROR); goto done; } @@ -222,7 +222,7 @@ GetEnvironmentVariableW( } else { - ASSERT("MultiByteToWideChar failed!\n"); + ASSERT("UTF-8 to UTF-16 conversion failed!\n"); SetLastError(ERROR_INTERNAL_ERROR); size = 0; *lpBuffer = '\0'; @@ -291,7 +291,7 @@ SetEnvironmentVariableW( if ((nameSize = lpName != nullptr ? (INT)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpName, PAL_wcslen(lpName) + 1, 0) : 0) == 0) { - ERROR("WideCharToMultiByte failed\n"); + ERROR("UTF-16 to UTF-8 conversion failed\n"); SetLastError(ERROR_INVALID_PARAMETER); goto done; } @@ -306,7 +306,7 @@ SetEnvironmentVariableW( if (0 == minipal_convert_utf16_to_utf8((const CHAR16_T*)lpName, PAL_wcslen(lpName) + 1, name, nameSize, 0)) { - ASSERT("WideCharToMultiByte returned 0\n"); + ASSERT("UTF-16 to UTF-8 conversion returned 0\n"); SetLastError(ERROR_INTERNAL_ERROR); goto done; } @@ -315,7 +315,7 @@ SetEnvironmentVariableW( { if ((valueSize = (INT)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpValue, PAL_wcslen(lpValue) + 1, 0)) == 0) { - ERROR("WideCharToMultiByte failed\n"); + ERROR("UTF-16 to UTF-8 conversion failed\n"); SetLastError(ERROR_INVALID_PARAMETER); goto done; } @@ -331,7 +331,7 @@ SetEnvironmentVariableW( if (0 == minipal_convert_utf16_to_utf8((const CHAR16_T*)lpValue, PAL_wcslen(lpValue) + 1, value, valueSize, 0)) { - ASSERT("WideCharToMultiByte failed\n"); + ASSERT("UTF-16 to UTF-8 conversion failed\n"); SetLastError( ERROR_INTERNAL_ERROR ); goto done; } diff --git a/src/coreclr/pal/tests/palsuite/CMakeLists.txt b/src/coreclr/pal/tests/palsuite/CMakeLists.txt index 28537e7882fdaa..249af9df4b44b7 100644 --- a/src/coreclr/pal/tests/palsuite/CMakeLists.txt +++ b/src/coreclr/pal/tests/palsuite/CMakeLists.txt @@ -235,15 +235,6 @@ add_executable_clr(paltests #locale_info/CompareStringW/test1/test1.cpp #locale_info/GetLocaleInfoW/test1/test1.cpp #locale_info/GetLocaleInfoW/test2/test2.cpp - locale_info/MultiByteToWideChar/test1/test1.cpp - locale_info/MultiByteToWideChar/test2/test2.cpp - locale_info/MultiByteToWideChar/test3/test3.cpp - locale_info/MultiByteToWideChar/test4/test4.cpp - locale_info/WideCharToMultiByte/test1/test1.cpp - locale_info/WideCharToMultiByte/test2/test2.cpp - locale_info/WideCharToMultiByte/test3/test3.cpp - locale_info/WideCharToMultiByte/test4/test4.cpp - locale_info/WideCharToMultiByte/test5/test5.cpp miscellaneous/CloseHandle/test1/test.cpp miscellaneous/CloseHandle/test2/test.cpp miscellaneous/FlushInstructionCache/test1/test1.cpp diff --git a/src/coreclr/pal/tests/palsuite/compilableTests.txt b/src/coreclr/pal/tests/palsuite/compilableTests.txt index d2b04a50e94fe2..76a34a41d2644d 100644 --- a/src/coreclr/pal/tests/palsuite/compilableTests.txt +++ b/src/coreclr/pal/tests/palsuite/compilableTests.txt @@ -161,15 +161,6 @@ loader/LoadLibraryW/test1/paltest_loadlibraryw_test1 loader/LoadLibraryW/test2/paltest_loadlibraryw_test2 loader/LoadLibraryW/test3/paltest_loadlibraryw_test3 loader/LoadLibraryW/test5/paltest_loadlibraryw_test5 -locale_info/MultiByteToWideChar/test1/paltest_multibytetowidechar_test1 -locale_info/MultiByteToWideChar/test2/paltest_multibytetowidechar_test2 -locale_info/MultiByteToWideChar/test3/paltest_multibytetowidechar_test3 -locale_info/MultiByteToWideChar/test4/paltest_multibytetowidechar_test4 -locale_info/WideCharToMultiByte/test1/paltest_widechartomultibyte_test1 -locale_info/WideCharToMultiByte/test2/paltest_widechartomultibyte_test2 -locale_info/WideCharToMultiByte/test3/paltest_widechartomultibyte_test3 -locale_info/WideCharToMultiByte/test4/paltest_widechartomultibyte_test4 -locale_info/WideCharToMultiByte/test5/paltest_widechartomultibyte_test5 miscellaneous/CloseHandle/test1/paltest_closehandle_test1 miscellaneous/CloseHandle/test2/paltest_closehandle_test2 miscellaneous/FlushInstructionCache/test1/paltest_flushinstructioncache_test1 diff --git a/src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/test1.cpp deleted file mode 100644 index bbd8ab11c00f69..00000000000000 --- a/src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/test1.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Tests MultiByteToWideChar with all the ASCII characters (0-127). -** Also tests that WideCharToMultiByte handles different buffer -** lengths correctly (0, -1, and a valid length) -** -** -**==========================================================================*/ - -#include - -/* - * For now, it is assumed that MultiByteToWideChar will only be used in the PAL - * with CP_ACP, and that dwFlags will be 0. - */ - -PALTEST(locale_info_MultiByteToWideChar_test1_paltest_multibytetowidechar_test1, "locale_info/MultiByteToWideChar/test1/paltest_multibytetowidechar_test1") -{ - char mbStr[128]; - WCHAR wideStr[128]; - int ret; - int i; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - for (i=0; i<128; i++) - { - mbStr[i] = 127 - i; - wideStr[i] = 0; - } - - - ret = MultiByteToWideChar(CP_ACP, 0, mbStr, -1, wideStr, 0); - if (ret != 128) - { - Fail("MultiByteToWideChar did not return correct string length!\n" - "Got %d, expected %d\n", ret, 128); - } - - /* Make sure the ASCII set (0-127) gets translated correctly */ - ret = MultiByteToWideChar(CP_ACP, 0, mbStr, -1, wideStr, 128); - if (ret != 128) - { - Fail("MultiByteToWideChar did not return correct string length!\n" - "Got %d, expected %d\n", ret, 128); - } - - for (i=0; i<128; i++) - { - if (wideStr[i] != (WCHAR)(127 - i)) - { - Fail("MultiByteToWideChar failed to translate correctly!\n" - "Expected character %d to be %c (%x), got %c (%x)\n", - i, 127 - i, 127 - i,wideStr[i], wideStr[i]); - } - } - - - /* try a 0 length string */ - mbStr[0] = 0; - ret = MultiByteToWideChar(CP_ACP, 0, mbStr, -1, wideStr, 0); - if (ret != 1) - { - Fail("MultiByteToWideChar did not return correct string length!\n" - "Got %d, expected %d\n", ret, 1); - } - - PAL_Terminate(); - - return PASS; -} - diff --git a/src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/test2.cpp b/src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/test2.cpp deleted file mode 100644 index e98b03db070fea..00000000000000 --- a/src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/test2.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test2.c -** -** Purpose: Tests that MultiByteToWideChar respects the length of the wide -** character string. - -** -**==========================================================================*/ - -#include - -/* - * For now, it is assumed that MultiByteToWideChar will only be used in the PAL - * with CP_ACP, and that dwFlags will be 0. - */ - -PALTEST(locale_info_MultiByteToWideChar_test2_paltest_multibytetowidechar_test2, "locale_info/MultiByteToWideChar/test2/paltest_multibytetowidechar_test2") -{ - char mbStr[128]; - WCHAR wideStr[128]; - int ret; - int i; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - for (i=0; i<128; i++) - { - mbStr[i] = 'a'; - wideStr[i] = 0; - } - - mbStr[127] = 0; - - - ret = MultiByteToWideChar(CP_ACP, 0, mbStr, 10, wideStr, 0); - if (ret != 10) - { - Fail("MultiByteToWideChar did not return correct string length!\n" - "Got %d, expected %d\n", ret, 10); - } - - wideStr[10] = (WCHAR) 'b'; - - ret = MultiByteToWideChar(CP_ACP, 0, mbStr, 10, wideStr, 128); - if (ret != 10) - { - Fail("MultiByteToWideChar did not return correct string length!\n" - "Got %d, expected %d\n", ret, 10); - } - - if (wideStr[10] != 'b') - { - Fail("WideCharToMultiByte overflowed the destination buffer!\n"); - } - - PAL_Terminate(); - - return PASS; -} - diff --git a/src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/test3.cpp b/src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/test3.cpp deleted file mode 100644 index 2e36b3e3a145b2..00000000000000 --- a/src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/test3.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test3.c -** -** Purpose: Tests that MultiByteToWideChar correctly handles the following -** error conditions: insufficient buffer space, invalid code pages, -** and invalid flags. -** -** -**==========================================================================*/ - -#include - - -PALTEST(locale_info_MultiByteToWideChar_test3_paltest_multibytetowidechar_test3, "locale_info/MultiByteToWideChar/test3/paltest_multibytetowidechar_test3") -{ - char mbStr[128]; - WCHAR wideStr[128]; - int ret; - int i; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - for (i=0; i<128; i++) - { - mbStr[i] = 'a'; - wideStr[i] = 0; - } - - mbStr[127] = 0; - - /* try with insufficient buffer space */ - ret = MultiByteToWideChar(CP_ACP, 0, mbStr, -1, wideStr, 10); - if (ret != 0) - { - Fail("MultiByteToWideChar did not return an error!\n" - "Expected return of 0, got %d", ret); - } - - ret = GetLastError(); - if (ret != ERROR_INSUFFICIENT_BUFFER) - { - Fail("MultiByteToWideChar did not set the last error to " - "ERROR_INSUFFICIENT_BUFFER!\n"); - } - - /* try with a wacky code page */ - ret = MultiByteToWideChar(-1, 0, mbStr, -1, wideStr, 128); - if (ret != 0) - { - Fail("MultiByteToWideChar did not return an error!\n" - "Expected return of 0, got %d", ret); - } - - ret = GetLastError(); - if (ret != ERROR_INVALID_PARAMETER) - { - Fail("MultiByteToWideChar did not set the last error to " - "ERROR_INVALID_PARAMETER!\n"); - } - - PAL_Terminate(); - - return PASS; -} - diff --git a/src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.cpp b/src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.cpp deleted file mode 100644 index 39bdbb1a11d0f0..00000000000000 --- a/src/coreclr/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.cpp +++ /dev/null @@ -1,282 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test4.c -** -** Purpose: Tests MultiByteToWideChar with a UTF-8 encoding -** -** -**==========================================================================*/ - -#include -#include - -PALTEST(locale_info_MultiByteToWideChar_test4_paltest_multibytetowidechar_test4, "locale_info/MultiByteToWideChar/test4/paltest_multibytetowidechar_test4") -{ - int ret; - int ret2; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - const char * const utf8Strings[] = - { - // Correct strings - - // Empty string - "", - // 1 byte encoded 1 character long string - "A", - // 2 byte encoded 1 character long string - "\xC2\x80", - // 3 byte encoded 1 character long string - "\xE0\xA0\x80", - // 1 byte encoded characters only - "ABCDEFGHIJKLMNOPQRSTUVWXYZ", - // valid 2 byte encoded characters only - "\xC2\x80\xC3\xBF\xC7\x81\xDF\xBF", - // valid 3 byte encoded characters only - "\xE0\xA0\x80\xE1\xB6\x88\xE1\x80\x80\xEF\xBF\xBF", - // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char - "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45", - // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one - "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF", - // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one - "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45", - // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char - "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF", - // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char - "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46", - // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one - "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF", - // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one - "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46", - // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char - "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF", - // surrogates - "\xF0\x90\x80\x80\xF0\x90\x89\x80\xF3\x80\x8E\xB0\xF4\x8F\xBF\xBF", - - // Strings with errors - // Incomplete 2 byte encoded character 1 byte missing standalone - "\xC2", - // Incomplete 3 byte encoded character 1 byte missing standalone - "\xE0\xA0", - // Incomplete 3 byte encoded character 2 bytes missing standalone - "\xE0", - // Incomplete surrogate character 1 byte missing standalone - "\xF0\x90\x80", - // Incomplete surrogate character 2 bytes missing standalone - "\xF0\x90", - // Incomplete surrogate character 3 bytes missing standalone - "\xF0", - // Trailing byte with no lead byte standalone - "\x80", - // Incomplete 2 byte encoded character 1 byte missing between 1 byte chars - "\x41\xC2\x42", - // Incomplete 3 byte encoded character 1 byte missing between 1 byte chars - "\x41\xE0\xA0\x42", - // Incomplete 3 byte encoded character 2 bytes missing between 1 byte chars - "\x41\xE0\x42", - // Trailing byte with no lead byte between 1 byte chars - "\x41\x80\x42", - // Incomplete 2 byte encoded character 1 byte missing before 1 byte char - "\xC2\x42", - // Incomplete 3 byte encoded character 1 byte missing before 1 byte char - "\xE0\xA0\x42", - // Incomplete 3 byte encoded character 2 bytes missing before 1 byte char - "\xE0\x42", - // Trailing byte with no lead byte before 1 byte char - "\x80\x42", - // Incomplete 2 byte encoded character 1 byte missing after 1 byte char - "\x41\xC2", - // Incomplete 3 byte encoded character 1 byte missing after 1 byte char - "\x41\xE0\xA0", - // Incomplete 3 byte encoded character 2 bytes missing after 1 byte char - "\x41\xE0", - // Trailing byte with no lead byte after 1 byte char - "\x41\x80", - // Incomplete 2 byte encoded character 1 byte missing between 2 byte chars - "\xC2\x80\xC2\xC3\xBF", - // Incomplete 3 byte encoded character 1 byte missing between 2 byte chars - "\xC2\x80\xE0\xA0\xC3\xBF", - // Incomplete 3 byte encoded character 2 bytes missing between 2 byte chars - "\xC2\x80\xE0\xC3\xBF", - // Trailing byte with no lead byte between 2 byte chars - "\xC2\x80\x80\xC3\xBF", - // 2 byte encoded character in non-shortest form encodings (these are not allowed) - "\xC0\x80", - // 3 byte encoded character in non-shortest form encodings (these are not allowed) - "\xE0\x80\x80", - // 4 byte encoded character in non-shortest form encodings (these are not allowed) - "\xF0\x80\x80\x80", - }; - - const WCHAR * const unicodeStrings[] = - { - // Empty string - W(""), - // 1 byte encoded 1 character long string - W("A"), - // 2 byte encoded 1 character long string - W("\x0080"), - // 3 byte encoded 1 character long string - W("\x0800"), - // 1 byte encoded characters only - W("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), - // 2 byte encoded characters only - W("\x0080\x00FF\x01C1\x07FF"), - // valid 3 byte encoded characters only - W("\x0800\x1D88\x1000\xFFFF"), - // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char - W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"), - // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one - W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"), - // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one - W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"), - // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char - W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"), - // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char - W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"), - // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one - W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF"), - // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one - W("\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"), - // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char - W("\x0080\x00FF\x0043\x0044\x01C1\x07FF"), - // surrogates - W("\xD800\xDC00\xD800\xDE40\xDAC0\xDFB0\xDBFF\xDFFF"), - - // Strings with errors - // Incomplete 2 byte encoded character standalone - W("\xFFFD"), - // Incomplete 3 byte encoded character 1 byte missing standalone - W("\xFFFD"), - // Incomplete 3 byte encoded character 2 bytes missing standalone - W("\xFFFD"), - // Incomplete surrogate character 1 byte missing standalone - W("\xFFFD"), - // Incomplete surrogate character 2 bytes missing standalone - W("\xFFFD"), - // Incomplete surrogate character 3 bytes missing standalone - W("\xFFFD"), - // Trailing byte with no lead byte standalone - W("\xFFFD"), - // Incomplete 2 byte encoded character 1 byte missing between 1 byte chars - W("\x0041\xFFFD\x0042"), - // Incomplete 3 byte encoded character 1 byte missing between 1 byte chars - W("\x0041\xFFFD\x0042"), - // Incomplete 3 byte encoded character 2 bytes missing between 1 byte chars - W("\x0041\xFFFD\x0042"), - // Trailing byte with no lead byte between 1 byte chars - W("\x0041\xFFFD\x0042"), - // Incomplete 2 byte encoded character 1 byte missing before 1 byte char - W("\xFFFD\x0042"), - // Incomplete 3 byte encoded character 1 byte missing before 1 byte char - W("\xFFFD\x0042"), - // Incomplete 3 byte encoded character 2 bytes missing before 1 byte char - W("\xFFFD\x0042"), - // Trailing byte with no lead byte before 1 byte char - W("\xFFFD\x0042"), - // Incomplete 2 byte encoded character 1 byte missing after 1 byte char - W("\x0041\xFFFD"), - // Incomplete 3 byte encoded character 1 byte missing after 1 byte char - W("\x0041\xFFFD"), - // Incomplete 3 byte encoded character 2 bytes missing after 1 byte char - W("\x0041\xFFFD"), - // Trailing byte with no lead byte after 1 byte char - W("\x0041\xFFFD"), - // Incomplete 2 byte encoded character 1 byte missing between 2 byte chars - W("\x0080\xFFFD\x00FF"), - // Incomplete 3 byte encoded character 1 byte missing between 2 byte chars - W("\x0080\xFFFD\x00FF"), - // Incomplete 3 byte encoded character 2 bytes missing between 2 byte chars - W("\x0080\xFFFD\x00FF"), - // Trailing byte with no lead byte between 2 byte chars - W("\x0080\xFFFD\x00FF"), - // 2 byte encoded character in non-shortest form encodings (these are not allowed) - W("\xFFFD\xFFFD"), - // 3 byte encoded character in non-shortest form encodings (these are not allowed) - W("\xFFFD\xFFFD"), - // 4 byte encoded character in non-shortest form encodings (these are not allowed) - W("\xFFFD\xFFFD\xFFFD"), - }; - - for (int i = 0; i < (sizeof(utf8Strings) / sizeof(utf8Strings[0])); i++) - { - ret = MultiByteToWideChar(CP_UTF8, 0, utf8Strings[i], -1, NULL, 0); - WCHAR* wideBuffer = (WCHAR*)malloc(ret * sizeof(WCHAR)); - ret2 = MultiByteToWideChar(CP_UTF8, 0, utf8Strings[i], -1, wideBuffer, ret); - if (ret != ret2) - { - Fail("MultiByteToWideChar string %d: returned different string length for empty and real dest buffers!\n" - "Got %d for the empty one, %d for real one.\n", i, ret2, ret); - } - - if (wcscmp(wideBuffer, unicodeStrings[i]) != 0) - { - Fail("MultiByteToWideChar string %d: the resulting string doesn't match the expected one!\n", i); - } - - free(wideBuffer); - } - - { - // U+6F22 — code unit > U+00FF catches long-code-path bugs that move - // only the low byte instead of performing a full 16-bit byte swap. - const char utf8[] = "\xE6\xBC\xA2"; - WCHAR wide[1] = { 0 }; - size_t n = minipal_convert_utf8_to_utf16(utf8, sizeof(utf8) - 1, (CHAR16_T*)wide, 1, 0); - if (n != 1 || wide[0] != 0x6F22) - Fail("utf8->utf16 produced 0x%04x (n=%zu)\n", wide[0], n); - -#if BIGENDIAN - wide[0] = 0; - n = minipal_convert_utf8_to_utf16(utf8, sizeof(utf8) - 1, (CHAR16_T*)wide, 1, MINIPAL_TREAT_AS_LITTLE_ENDIAN); - if (n != 1 || wide[0] != 0x226F) - Fail("treat-as-LE utf8->utf16 produced 0x%04x (n=%zu)\n", wide[0], n); -#endif - } - -#if BIGENDIAN - { - const char* ascii = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"; - const size_t asciiLengthWithTerminator = strlen(ascii) + 1; - const unsigned int flags = MINIPAL_TREAT_AS_LITTLE_ENDIAN; - - size_t requiredLength = minipal_get_length_utf8_to_utf16(ascii, asciiLengthWithTerminator, flags); - if (requiredLength != asciiLengthWithTerminator) - { - Fail("minipal_get_length_utf8_to_utf16 with MINIPAL_TREAT_AS_LITTLE_ENDIAN returned %zu, expected %zu\n", - requiredLength, asciiLengthWithTerminator); - } - - WCHAR wideBuffer[64]; - size_t convertedLength = minipal_convert_utf8_to_utf16(ascii, asciiLengthWithTerminator, - (CHAR16_T*)wideBuffer, sizeof(wideBuffer) / sizeof(wideBuffer[0]), flags); - - if (convertedLength != asciiLengthWithTerminator) - { - Fail("minipal_convert_utf8_to_utf16 with MINIPAL_TREAT_AS_LITTLE_ENDIAN returned %zu, expected %zu\n", - convertedLength, asciiLengthWithTerminator); - } - - for (size_t i = 0; i < asciiLengthWithTerminator; i++) - { - WCHAR expected = (WCHAR)(((unsigned char)ascii[i]) << 8); - if (wideBuffer[i] != expected) - { - Fail("minipal_convert_utf8_to_utf16 with MINIPAL_TREAT_AS_LITTLE_ENDIAN mismatch at %zu: got 0x%04x expected 0x%04x\n", - i, wideBuffer[i], expected); - } - } - } -#endif - - PAL_Terminate(); - - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.cpp deleted file mode 100644 index e8197b8c11b4c3..00000000000000 --- a/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Tests WideCharToMultiByte with all the ASCII characters (0-127). -** Also tests that WideCharToMultiByte handles different buffer -** lengths correctly (0, -1, and a valid length) -** -** -**==========================================================================*/ - -#include - -PALTEST(locale_info_WideCharToMultiByte_test1_paltest_widechartomultibyte_test1, "locale_info/WideCharToMultiByte/test1/paltest_widechartomultibyte_test1") -{ - char mbStr[128]; - WCHAR wideStr[128]; - int ret; - int i; - int k; - BOOL bRet=TRUE; - - /* These codepages are currently supported by the PAL */ - int codePages[] ={ - CP_ACP, - CP_UTF8 - }; - - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - /* Go through all of the code pages */ - for(i=0; i<(sizeof(codePages)/sizeof(int)); i++) - { - - for (k=0; k<128; k++) - { - wideStr[k] = 127 - k; - mbStr[k] = 0; - } - - /* Convert with buffer size of 0 */ - ret = WideCharToMultiByte(codePages[i], 0, wideStr, -1, - mbStr, 0, NULL, NULL); - if (ret != 128) - { - Trace("WideCharToMultiByte did not return correct string length!\n" - "Got %d, expected %d for code page %d with error %u.\n", - ret, 128,codePages[i],GetLastError()); - bRet=FALSE; - } - - /* Make sure the ASCII set (0-127) gets translated correctly */ - ret = WideCharToMultiByte(codePages[i], 0, wideStr, -1, - mbStr, 128, NULL, NULL); - if (ret != 128) - { - Trace("WideCharToMultiByte did not return correct string length!\n" - "Got %d, expected %d for code page %d with error %u.\n", - ret, 128,codePages[i],GetLastError()); - bRet=FALSE; - } - - for (k=0; k<128; k++) - { - if (mbStr[k] != 127 - k) - { - Trace("WideCharToMultiByte failed to translate correctly!\n" - "Expected character %d to be %c (%x), got %c (%x) for " - "code page %d\n",k, 127 - k, 127 - k,mbStr[k], mbStr[k], - codePages[i]); - bRet=FALSE; - } - } - - - /* try a 0 length string ("") */ - wideStr[0] = '\0'; - ret = WideCharToMultiByte(codePages[i], 0, wideStr, -1, - mbStr, 0, NULL, NULL); - if (ret != 1) - { - Trace("WideCharToMultiByte did not return correct string length!\n" - "Got %d, expected %d for code page %d with error %u.\n", - ret, 1,codePages[i],GetLastError()); - bRet=FALSE; - } - } - - int result = bRet ? PASS : FAIL; - PAL_TerminateEx(result); - return result; -} - diff --git a/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.cpp b/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.cpp deleted file mode 100644 index 611b1b92b1b1fa..00000000000000 --- a/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test2.c -** -** Purpose: Tests that WideCharToMultiByte respects the length of the wide -** character string. -** -** -**==========================================================================*/ - -#include - - -PALTEST(locale_info_WideCharToMultiByte_test2_paltest_widechartomultibyte_test2, "locale_info/WideCharToMultiByte/test2/paltest_widechartomultibyte_test2") -{ - char mbStr[128]; - WCHAR wideStr[128]; - int ret; - int i; - int k; - BOOL bRet=TRUE; - - /* These codepages are currently supported by the PAL */ - int codePages[] ={ - CP_ACP, - CP_UTF8 - }; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - /* Go through all of the code pages */ - for(i=0; i<(sizeof(codePages)/sizeof(int)); i++) - { - - /* Filling the arrays */ - for (k=0; k<128; k++) - { - wideStr[k] = 'a'; - mbStr[i] = 0; - } - - wideStr[127] = 0; - - /* Passing a buffer that is too small */ - ret = WideCharToMultiByte(codePages[i], 0, wideStr, 10, - mbStr, 0, NULL, NULL); - if (ret != 10) - { - Trace("WideCharToMultiByte did not return correct string length!\n" - "Got %d, expected %d for %d with error %u.\n", ret, 10, - codePages[i], GetLastError()); - bRet = FALSE; - } - - /* Passing a sufficiently large buffer */ - mbStr[10] = 'b'; - ret = WideCharToMultiByte(codePages[i], 0, wideStr, 10, - mbStr, 128, NULL, NULL); - if (ret != 10) - { - Trace("WideCharToMultiByte did not return correct string length!\n" - "Got %d, expected %d for code page %d with error %u.\n", - ret, 10, codePages[i], GetLastError()); - bRet = FALSE; - } - - /* Verifying overflow of the destination string did not occur */ - if (mbStr[10] != 'b') - { - Trace("WideCharToMultiByte overflowed the destination buffer for " - "code page %d.\n", codePages[i]); - bRet = FALSE; - } - - } - - int result = bRet ? PASS : FAIL; - PAL_TerminateEx(result); - return result; -} - diff --git a/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.cpp b/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.cpp deleted file mode 100644 index 3bb816dcb88332..00000000000000 --- a/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test3.c -** -** Purpose: Tests that WideCharToMultiByte correctly handles the following -** error conditions: insufficient buffer space, invalid code pages, -** and invalid flags. -** -** -**==========================================================================*/ - - -#include - - -PALTEST(locale_info_WideCharToMultiByte_test3_paltest_widechartomultibyte_test3, "locale_info/WideCharToMultiByte/test3/paltest_widechartomultibyte_test3") -{ - char mbStr[128]; - WCHAR wideStr[128]; - int ret; - int i; - int k; - BOOL bRet=TRUE; - - /* These codepages are currently supported by the PAL */ - int codePages[] ={ - CP_ACP, - CP_UTF8 - }; - - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - /* Go through all of the code pages */ - for(i=0; i<(sizeof(codePages)/sizeof(int)); i++) - { - - for (k=0; k<128; k++) - { - wideStr[k] = 'a'; - mbStr[k] = 0; - } - - wideStr[127] = 0; - - /* try with insufficient buffer space */ - ret = WideCharToMultiByte(codePages[i], 0, wideStr, -1, - mbStr, 10, NULL, NULL); - if (ret != 0) - { - Trace("WideCharToMultiByte did not return an error!\n" - "Expected return of 0, got %d for code page %d.\n", ret, - codePages[i]); - bRet = FALSE; - } - - ret = GetLastError(); - if (ret != ERROR_INSUFFICIENT_BUFFER) - { - Fail("WideCharToMultiByte set the last error to %u instead of " - "ERROR_INSUFFICIENT_BUFFER for code page %d.\n", - GetLastError(),codePages[i]); - bRet = FALSE; - } - } - - /* Return failure if any of the code pages returned the wrong results */ - if(!bRet) - { - return FAIL; - } - - /* try with a wacky code page */ - ret = WideCharToMultiByte(-1, 0, wideStr, -1, mbStr, 128, NULL, NULL); - if (ret != 0) - { - Fail("WideCharToMultiByte did not return an error!\n" - "Expected return of 0, got %d for invalid code page.\n", ret); - } - - ret = GetLastError(); - if (ret != ERROR_INVALID_PARAMETER) - { - Fail("WideCharToMultiByte set the last error to %u instead of " - "ERROR_INVALID_PARAMETER for invalid code page -1.\n", - GetLastError()); - } - - PAL_Terminate(); - - return PASS; -} - diff --git a/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/test4.cpp b/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/test4.cpp deleted file mode 100644 index 19b5796bf1f593..00000000000000 --- a/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/test4.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test4.c -** -** Purpose: Tests that WideCharToMultiByte correctly handles WC_NO_BEST_FIT_CHARS -** -** -**==========================================================================*/ - - -#include - -/* C with a circumflex */ -char16_t ustr[2] = { 0x108, 0 }; - -/* expected conversion when best fit is allowed on Windows */ -char* lpBestFitRes = "C"; - -/* expected conversion when no default character is specified */ -char* lpResStr1 = "?"; - -/* expected conversion when the default character is 'k' */ -char myDefaultChar = 'k'; -char* lpResStr2 = "k"; - -int -TestWideCharToMultiByte( - IN UINT CodePage, - IN DWORD dwFlags, - IN LPCSTR lpDefaultChar, - IN LPSTR lpResStr) -{ - char mbstr[30]; - int ret; - int testStatus = PASS; - BOOL usedDefaultChar = FALSE; - - printf("WideCharToMultiByte (CodePage=%d, dwFlags=%#x, default=%c)\n", - CodePage, dwFlags, lpDefaultChar?*lpDefaultChar:' '); - ret = WideCharToMultiByte(CodePage, dwFlags, ustr, -1, mbstr, sizeof(mbstr), - lpDefaultChar, &usedDefaultChar); - if (ret != 0) { - printf(" converted C with circumflex to in Unicode to multibyte: " - "\"%s\"\n", mbstr); - printf(" used default character?: %d\n", usedDefaultChar); - if (strcmp(mbstr, lpResStr) != 0 || usedDefaultChar != TRUE) - { - printf("!!!! failed conversion !!!!\n"); - testStatus = FAIL; - } - } - else { - printf("!!!! failed conversion !!!!\n"); - testStatus = FAIL; - } - return testStatus; -} - -PALTEST(locale_info_WideCharToMultiByte_test4_paltest_widechartomultibyte_test4, "locale_info/WideCharToMultiByte/test4/paltest_widechartomultibyte_test4") -{ - int testStatus = PASS; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - /* Use WideCharToMultiByte to convert the string in code page CP_ACP. - * Note that the resulting string will be different on Windows PAL and - * Unix PAL. On Windows, the default best fit behavior will map C with - * circumflex to C. - * - * testStatus |= TestWideCharToMultiByte(CP_ACP, 0, NULL, lpBestFitRes); - * - * On Unix, where there is no support for finding best fit, it will be - * mapped to a '?'. In addition, it will trigger an ASSERT in the dbg/chk - * builds. - * - * testStatus |= TestWideCharToMultiByte(CP_ACP, 0, NULL, lpResStr1); - */ - - /* Use WideCharToMultiByte with WC_NO_BEST_FIR_CHARS to convert the string - * in CP_ACP (1252 by default). This will prevent it from mapping the C - * with circumflex to its closest match in the ANSI code page: C - */ - testStatus |= TestWideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, NULL, lpResStr1); - - - /* Use WideCharToMultiByte with WC_NO_BEST_FIR_CHARS and a default character - * to convert the string. This will prevent it from mapping the C with - * circumflex to its closest match in the ANSI code page: C. It will be - * replaced with the specified default character. - */ - testStatus |= TestWideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, &myDefaultChar, lpResStr2); - - /* Use WideCharToMultiByte to convert the string in code page 1253 - * Note that the resulting string will be different on Windows PAL and - * Unix PAL. On Windows, the default best fit behavior will map C with - * circumflex to C. - * - * testStatus |= TestWideCharToMultiByte(1253, 0, NULL, lpBestFitRes); - * - * On Unix, where there is no support for finding best fit, it will be - * mapped to a '?'. In addition, it will trigger an ASSERT in the dbg/chk - * builds. - * - * testStatus |= TestWideCharToMultiByte(1253, 0, NULL, lpResStr1); - */ - - /* Use WideCharToMultiByte with WC_NO_BEST_FIR_CHARS to convert the string - * in 1253. This will prevent it from mapping the C - * with circumflex to its closest match in the ANSI code page: C - */ - testStatus |= TestWideCharToMultiByte(1253, WC_NO_BEST_FIT_CHARS, NULL, lpResStr1); - - /* Use WideCharToMultiByte with WC_NO_BEST_FIR_CHARS and a default - * character to convert the string in 1253. This will prevent it from - * mapping the C with circumflex to its closest match in the ANSI code - * page: C. It will be replaced with the specified default character. - */ - testStatus |= TestWideCharToMultiByte(1253, WC_NO_BEST_FIT_CHARS, &myDefaultChar, lpResStr2); - - PAL_TerminateEx(testStatus); - - return testStatus; -} - diff --git a/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.cpp b/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.cpp deleted file mode 100644 index c968e5cca7a4aa..00000000000000 --- a/src/coreclr/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.cpp +++ /dev/null @@ -1,261 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test4.c -** -** Purpose: Tests WideCharMultiByte with UTF-8 encoding -** -** -**==========================================================================*/ - -#include -#include - -PALTEST(locale_info_WideCharToMultiByte_test5_paltest_widechartomultibyte_test5, "locale_info/WideCharToMultiByte/test5/paltest_widechartomultibyte_test5") -{ - int ret; - int ret2; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - const WCHAR * const unicodeStrings[] = - { - // Correct strings - - // Empty string - W(""), - // 1 byte encoded 1 character long string - W("A"), - // 2 byte encoded 1 character long string - W("\x0080"), - // 3 byte encoded 1 character long string - W("\x0800"), - // 1 byte encoded characters only - W("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), - // 2 byte encoded characters only - W("\x0080\x00FF\x01C1\x07FF"), - // valid 3 byte encoded characters only - W("\x0800\x1D88\x1000\xFFFF"), - // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char - W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"), - // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one - W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"), - // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one - W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"), - // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char - W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"), - // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char - W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"), - // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one - W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF"), - // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one - W("\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"), - // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char - W("\x0080\x00FF\x0043\x0044\x01C1\x07FF"), - // Surrogates - W("\xD800\xDC00\xD800\xDE40\xDAC0\xDFB0\xDBFF\xDFFF"), - - // Strings with errors - - // Single high surrogate - W("\xD800"), - // Single low surrogate - W("\xDC00"), - // Character followed by single high surrogate - W("\x0041\xD800"), - // Character followed by single low surrogate - W("\x0041\xDC00"), - // Single high surrogate between two characters - W("\x0041\xD800\x0042"), - // Single low surrogate between two characters - W("\x0041\xDC00\x0042"), - // 256 single high surrogates - W("\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800" - "\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800\xD800") - }; - - const char * const utf8Strings[] = - { - // Correct strings - - // Empty string - "", - // 1 byte encoded 1 character long string - "A", - // 2 byte encoded 1 character long string - "\xC2\x80", - // 3 byte encoded 1 character long string - "\xE0\xA0\x80", - // 1 byte encoded characters only - "ABCDEFGHIJKLMNOPQRSTUVWXYZ", - // valid 2 byte encoded characters only - "\xC2\x80\xC3\xBF\xC7\x81\xDF\xBF", - // valid 3 byte encoded characters only - "\xE0\xA0\x80\xE1\xB6\x88\xE1\x80\x80\xEF\xBF\xBF", - // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char - "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45", - // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one - "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF", - // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one - "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45", - // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char - "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF", - // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char - "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46", - // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one - "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF", - // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one - "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46", - // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char - "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF", - // Surrogates - "\xF0\x90\x80\x80\xF0\x90\x89\x80\xF3\x80\x8E\xB0\xF4\x8F\xBF\xBF", - - // Strings with errors - - // Single high surrogate - "\xEF\xBF\xBD", - // Single low surrogate - "\xEF\xBF\xBD", - // Character followed by single high surrogate - "\x41\xEF\xBF\xBD", - // Character followed by single low surrogate - "\x41\xEF\xBF\xBD", - // Single high surrogate between two characters - "\x41\xEF\xBF\xBD\x42", - // Single low surrogate between two characters - "\x41\xEF\xBF\xBD\x42", - // 256 single high surrogates - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD" - }; - - for (int i = 0; i < (sizeof(unicodeStrings) / sizeof(unicodeStrings[0])); i++) - { - ret = WideCharToMultiByte(CP_UTF8, 0, unicodeStrings[i], -1, NULL, 0, NULL, NULL); - CHAR* utf8Buffer = (CHAR*)malloc(ret * sizeof(CHAR)); - ret2 = WideCharToMultiByte(CP_UTF8, 0, unicodeStrings[i], -1, utf8Buffer, ret, NULL, NULL); - if (ret != ret2) - { - Fail("WideCharToMultiByte string %d: returned different string length for empty and real dest buffers!\n" - "Got %d for the empty one, %d for real one.\n", i, ret2, ret); - } - - if (strcmp(utf8Buffer, utf8Strings[i]) != 0) - { - Fail("WideCharToMultiByte string %d: the resulting string doesn't match the expected one!\n", i); - } - - free(utf8Buffer); - } - - { - // U+6F22 — code unit > U+00FF catches long-code-path bugs that move - // only the low byte instead of performing a full 16-bit byte swap. - const WCHAR srcNative[1] = { 0x6F22 }; - CHAR utf8[4] = { 0 }; - size_t n = minipal_convert_utf16_to_utf8((const CHAR16_T*)srcNative, 1, utf8, sizeof(utf8), 0); - if (n != 3 || memcmp(utf8, "\xE6\xBC\xA2", 3) != 0) - Fail("utf16->utf8 produced %02x %02x %02x (n=%zu)\n", - (unsigned char)utf8[0], (unsigned char)utf8[1], (unsigned char)utf8[2], n); - -#if BIGENDIAN - // Stored little-endian (22 6F) reads as BE word 0x226F. - const WCHAR srcLE[1] = { 0x226F }; - memset(utf8, 0, sizeof(utf8)); - n = minipal_convert_utf16_to_utf8((const CHAR16_T*)srcLE, 1, utf8, sizeof(utf8), MINIPAL_TREAT_AS_LITTLE_ENDIAN); - if (n != 3 || memcmp(utf8, "\xE6\xBC\xA2", 3) != 0) - Fail("treat-as-LE utf16->utf8 produced %02x %02x %02x (n=%zu)\n", - (unsigned char)utf8[0], (unsigned char)utf8[1], (unsigned char)utf8[2], n); -#endif - } - -#if BIGENDIAN - { - const char* expected = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"; - const size_t expectedLengthWithTerminator = strlen(expected) + 1; - const unsigned int flags = MINIPAL_TREAT_AS_LITTLE_ENDIAN; - - WCHAR littleEndianWide[64]; - for (size_t i = 0; i < expectedLengthWithTerminator; i++) - { - littleEndianWide[i] = (WCHAR)(((unsigned char)expected[i]) << 8); - } - - size_t requiredLength = minipal_get_length_utf16_to_utf8((const CHAR16_T*)littleEndianWide, - expectedLengthWithTerminator, flags); - if (requiredLength != expectedLengthWithTerminator) - { - Fail("minipal_get_length_utf16_to_utf8 with MINIPAL_TREAT_AS_LITTLE_ENDIAN returned %zu, expected %zu\n", - requiredLength, expectedLengthWithTerminator); - } - - CHAR utf8Buffer[64]; - size_t convertedLength = minipal_convert_utf16_to_utf8((const CHAR16_T*)littleEndianWide, - expectedLengthWithTerminator, utf8Buffer, sizeof(utf8Buffer), flags); - if (convertedLength != expectedLengthWithTerminator) - { - Fail("minipal_convert_utf16_to_utf8 with MINIPAL_TREAT_AS_LITTLE_ENDIAN returned %zu, expected %zu\n", - convertedLength, expectedLengthWithTerminator); - } - - if (memcmp(utf8Buffer, expected, expectedLengthWithTerminator) != 0) - { - Fail("minipal_convert_utf16_to_utf8 with MINIPAL_TREAT_AS_LITTLE_ENDIAN produced unexpected bytes\n"); - } - } -#endif - - PAL_Terminate(); - - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/paltestlist.txt b/src/coreclr/pal/tests/palsuite/paltestlist.txt index fabaebdf172687..edb96612bd0cfa 100644 --- a/src/coreclr/pal/tests/palsuite/paltestlist.txt +++ b/src/coreclr/pal/tests/palsuite/paltestlist.txt @@ -141,14 +141,6 @@ loader/LoadLibraryA/test5/paltest_loadlibrarya_test5 loader/LoadLibraryW/test2/paltest_loadlibraryw_test2 loader/LoadLibraryW/test3/paltest_loadlibraryw_test3 loader/LoadLibraryW/test5/paltest_loadlibraryw_test5 -locale_info/MultiByteToWideChar/test1/paltest_multibytetowidechar_test1 -locale_info/MultiByteToWideChar/test2/paltest_multibytetowidechar_test2 -locale_info/MultiByteToWideChar/test3/paltest_multibytetowidechar_test3 -locale_info/MultiByteToWideChar/test4/paltest_multibytetowidechar_test4 -locale_info/WideCharToMultiByte/test1/paltest_widechartomultibyte_test1 -locale_info/WideCharToMultiByte/test2/paltest_widechartomultibyte_test2 -locale_info/WideCharToMultiByte/test3/paltest_widechartomultibyte_test3 -locale_info/WideCharToMultiByte/test5/paltest_widechartomultibyte_test5 miscellaneous/CloseHandle/test1/paltest_closehandle_test1 miscellaneous/CloseHandle/test2/paltest_closehandle_test2 miscellaneous/FlushInstructionCache/test1/paltest_flushinstructioncache_test1 diff --git a/src/coreclr/pal/tests/palsuite/paltestlist_to_be_reviewed.txt b/src/coreclr/pal/tests/palsuite/paltestlist_to_be_reviewed.txt index 2ef293d3841a24..cff14c085a9dbb 100644 --- a/src/coreclr/pal/tests/palsuite/paltestlist_to_be_reviewed.txt +++ b/src/coreclr/pal/tests/palsuite/paltestlist_to_be_reviewed.txt @@ -52,7 +52,6 @@ locale_info/CompareStringA/test1/paltest_comparestringa_test1 locale_info/CompareStringW/test1/paltest_comparestringw_test1 locale_info/GetLocaleInfoW/test1/paltest_getlocaleinfow_test1 locale_info/GetLocaleInfoW/test2/paltest_getlocaleinfow_test2 -locale_info/WideCharToMultiByte/test4/paltest_widechartomultibyte_test4 miscellaneous/FormatMessageW/test4/paltest_formatmessagew_test4 miscellaneous/FormatMessageW/test5/paltest_formatmessagew_test5 miscellaneous/FormatMessageW/test6/paltest_formatmessagew_test6 From 521d2a792a89aed88f477d6e21110e24d2edde09 Mon Sep 17 00:00:00 2001 From: am11 <3840695+am11@users.noreply.github.com> Date: Wed, 4 Nov 2026 21:56:18 +0200 Subject: [PATCH 04/13] Revert two windows callsites affected by codepage --- src/coreclr/vm/interoputil.cpp | 9 +++++++++ src/coreclr/vm/util.cpp | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/coreclr/vm/interoputil.cpp b/src/coreclr/vm/interoputil.cpp index d0b5f1fdb5224e..76d7bfc0dcab94 100644 --- a/src/coreclr/vm/interoputil.cpp +++ b/src/coreclr/vm/interoputil.cpp @@ -621,7 +621,12 @@ HRESULT GetStringizedTypeLibGuidForAssembly(Assembly *pAssembly, CQuickArrayGetSimpleName(); cbName=(ULONG)strlen(pszName); +#ifdef TARGET_WINDOWS + // The GUID is generated from the converted name, so the conversion must not change + cchName = MultiByteToWideChar(CP_ACP,0, pszName,cbName+1, 0,0); +#else cchName = (ULONG)minipal_get_length_utf8_to_utf16(pszName, cbName+1, 0); +#endif // See if there is a public key. EX_TRY @@ -686,7 +691,11 @@ HRESULT GetStringizedTypeLibGuidForAssembly(Assembly *pAssembly, CQuickArray(buffer.AllocThrows(byteCount)); + if (WideCharToMultiByte(codePage, 0, pwzString, -1, pStr, byteCount, nullptr, nullptr) == 0) + { + ThrowWin32(ERROR_NO_UNICODE_TRANSLATION); + } +#else size_t cchString = u16_strlen(pwzString) + 1; size_t byteCount = minipal_get_length_utf16_to_utf8((const CHAR16_T*)pwzString, cchString, 0); CQuickBytes buffer; char* pStr = static_cast(buffer.AllocThrows(byteCount)); minipal_convert_utf16_to_utf8((const CHAR16_T*)pwzString, cchString, pStr, byteCount, 0); +#endif PrintToStdErrA(pStr); } From 85cdee221d2e95f700cdd1e61855a49374917d60 Mon Sep 17 00:00:00 2001 From: am11 <3840695+am11@users.noreply.github.com> Date: Thu, 5 Nov 2026 01:43:33 +0200 Subject: [PATCH 05/13] Move tests under src/tests/minipal --- src/tests/CMakeLists.txt | 2 +- .../{tracing/eventpipe/native => }/minipal/CMakeLists.txt | 8 +++++--- src/tests/minipal/Directory.Build.props | 4 ++++ src/tests/minipal/Directory.Build.targets | 4 ++++ .../eventpipe/native => }/minipal/NativeMinipalTests.cs | 0 .../native => }/minipal/NativeMinipalTests.csproj | 0 .../native => }/minipal/native-minipal-tests-driver.c | 0 .../{tracing/eventpipe/native => }/minipal/utf8-tests.c | 0 8 files changed, 14 insertions(+), 4 deletions(-) rename src/tests/{tracing/eventpipe/native => }/minipal/CMakeLists.txt (67%) create mode 100644 src/tests/minipal/Directory.Build.props create mode 100644 src/tests/minipal/Directory.Build.targets rename src/tests/{tracing/eventpipe/native => }/minipal/NativeMinipalTests.cs (100%) rename src/tests/{tracing/eventpipe/native => }/minipal/NativeMinipalTests.csproj (100%) rename src/tests/{tracing/eventpipe/native => }/minipal/native-minipal-tests-driver.c (100%) rename src/tests/{tracing/eventpipe/native => }/minipal/utf8-tests.c (100%) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index a0c26e25719cd2..e5a148ddfb4c56 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -7,7 +7,7 @@ include(${CLR_ENG_NATIVE_DIR}/configurecompiler.cmake) include_directories("${CLR_SRC_NATIVE_DIR}") -add_subdirectory(${CLR_SRC_NATIVE_DIR}/minipal minipal) +add_subdirectory(${CLR_SRC_NATIVE_DIR}/minipal shared_minipal) list(APPEND LINK_LIBRARIES_ADDITIONAL PRIVATE minipal) # Add this subdir. We install the headers for the jit. diff --git a/src/tests/tracing/eventpipe/native/minipal/CMakeLists.txt b/src/tests/minipal/CMakeLists.txt similarity index 67% rename from src/tests/tracing/eventpipe/native/minipal/CMakeLists.txt rename to src/tests/minipal/CMakeLists.txt index 84adfbc33756e3..445487d2000ce8 100644 --- a/src/tests/tracing/eventpipe/native/minipal/CMakeLists.txt +++ b/src/tests/minipal/CMakeLists.txt @@ -7,12 +7,14 @@ endif() include_directories(${CLR_SRC_NATIVE_DIR}) +set(NATIVE_TEST_COMMON_DIR ../tracing/eventpipe/native/common) + add_executable(NativeMinipalTestsDriver - ../common/driver.c - ../common/test.c + ${NATIVE_TEST_COMMON_DIR}/driver.c + ${NATIVE_TEST_COMMON_DIR}/test.c native-minipal-tests-driver.c utf8-tests.c) -target_include_directories(NativeMinipalTestsDriver PRIVATE ../common) +target_include_directories(NativeMinipalTestsDriver PRIVATE ${NATIVE_TEST_COMMON_DIR}) target_link_libraries(NativeMinipalTestsDriver PRIVATE minipal) install(TARGETS NativeMinipalTestsDriver DESTINATION bin) diff --git a/src/tests/minipal/Directory.Build.props b/src/tests/minipal/Directory.Build.props new file mode 100644 index 00000000000000..6fac0339d0408f --- /dev/null +++ b/src/tests/minipal/Directory.Build.props @@ -0,0 +1,4 @@ + + + + diff --git a/src/tests/minipal/Directory.Build.targets b/src/tests/minipal/Directory.Build.targets new file mode 100644 index 00000000000000..8baf73e3ee0ea1 --- /dev/null +++ b/src/tests/minipal/Directory.Build.targets @@ -0,0 +1,4 @@ + + + + diff --git a/src/tests/tracing/eventpipe/native/minipal/NativeMinipalTests.cs b/src/tests/minipal/NativeMinipalTests.cs similarity index 100% rename from src/tests/tracing/eventpipe/native/minipal/NativeMinipalTests.cs rename to src/tests/minipal/NativeMinipalTests.cs diff --git a/src/tests/tracing/eventpipe/native/minipal/NativeMinipalTests.csproj b/src/tests/minipal/NativeMinipalTests.csproj similarity index 100% rename from src/tests/tracing/eventpipe/native/minipal/NativeMinipalTests.csproj rename to src/tests/minipal/NativeMinipalTests.csproj diff --git a/src/tests/tracing/eventpipe/native/minipal/native-minipal-tests-driver.c b/src/tests/minipal/native-minipal-tests-driver.c similarity index 100% rename from src/tests/tracing/eventpipe/native/minipal/native-minipal-tests-driver.c rename to src/tests/minipal/native-minipal-tests-driver.c diff --git a/src/tests/tracing/eventpipe/native/minipal/utf8-tests.c b/src/tests/minipal/utf8-tests.c similarity index 100% rename from src/tests/tracing/eventpipe/native/minipal/utf8-tests.c rename to src/tests/minipal/utf8-tests.c From fad6ae568436855eef8befb15e0ef43388c4998a Mon Sep 17 00:00:00 2001 From: am11 <3840695+am11@users.noreply.github.com> Date: Thu, 5 Nov 2026 01:52:30 +0200 Subject: [PATCH 06/13] Don't crash on null config as before --- src/coreclr/vm/gcenv.ee.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/coreclr/vm/gcenv.ee.cpp b/src/coreclr/vm/gcenv.ee.cpp index cbda6116a170ac..cabb60d009b085 100644 --- a/src/coreclr/vm/gcenv.ee.cpp +++ b/src/coreclr/vm/gcenv.ee.cpp @@ -1414,13 +1414,14 @@ bool GCToEEInterface::GetStringConfigValue(const char* privateKey, const char* p return false; } out = Configuration::GetKnobStringValue(configKey); - if (out == NULL) - { - return false; - } } } + if (out == NULL) + { + return false; + } + size_t cchOut = u16_strlen(out) + 1; int charCount = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)out, cchOut, 0); if (charCount == 0) From 396c7ad55872376630e46700893f87b6d9eb8434 Mon Sep 17 00:00:00 2001 From: am11 <3840695+am11@users.noreply.github.com> Date: Thu, 5 Nov 2026 03:11:56 +0200 Subject: [PATCH 07/13] Address review feedback - Report truncation for a null metadata string buffer with a nonzero size instead of writing through it. - Reject null paths in PAL CreateDirectoryW and CreateFileW before converting. - Keep the ANSI code page for the dbghelp SymInitialize search path. - Reserve room for a 255 character field name in bulk statics events. Co-authored-by: Cursor --- src/coreclr/md/enc/metamodelrw.cpp | 2 +- src/coreclr/md/runtime/metamodelro.cpp | 2 +- src/coreclr/pal/src/file/directory.cpp | 7 +++++++ src/coreclr/pal/src/file/file.cpp | 8 ++++++-- src/coreclr/utilcode/stacktrace.cpp | 9 ++++----- src/coreclr/vm/eventtrace_bulktype.cpp | 8 ++++---- src/coreclr/vm/eventtracepriv.h | 9 ++++++++- 7 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/coreclr/md/enc/metamodelrw.cpp b/src/coreclr/md/enc/metamodelrw.cpp index 7f3500546a0ee2..884c9e0a57a7b5 100644 --- a/src/coreclr/md/enc/metamodelrw.cpp +++ b/src/coreclr/md/enc/metamodelrw.cpp @@ -3838,7 +3838,7 @@ CMiniMdRW::Impl_GetStringW( if (cchBuffer == 0) iSize = (int)minipal_get_length_utf8_to_utf16(szString, cchString, 0); else - iSize = (int)minipal_convert_utf8_to_utf16(szString, cchString, (CHAR16_T*)szOut, cchBuffer, 0); + iSize = szOut != NULL ? (int)minipal_convert_utf8_to_utf16(szString, cchString, (CHAR16_T*)szOut, cchBuffer, 0) : 0; if (iSize == 0) { // Truncation error; get the size required. diff --git a/src/coreclr/md/runtime/metamodelro.cpp b/src/coreclr/md/runtime/metamodelro.cpp index 986756b03bac57..202001284a5c4d 100644 --- a/src/coreclr/md/runtime/metamodelro.cpp +++ b/src/coreclr/md/runtime/metamodelro.cpp @@ -121,7 +121,7 @@ CMiniMd::Impl_GetStringW( if (cchBuffer == 0) iSize = (int)minipal_get_length_utf8_to_utf16(szString, cchString, 0); else - iSize = (int)minipal_convert_utf8_to_utf16(szString, cchString, (CHAR16_T*)szOut, cchBuffer, 0); + iSize = szOut != NULL ? (int)minipal_convert_utf8_to_utf16(szString, cchString, (CHAR16_T*)szOut, cchBuffer, 0) : 0; if (iSize == 0) { // Truncation error; get the size required. diff --git a/src/coreclr/pal/src/file/directory.cpp b/src/coreclr/pal/src/file/directory.cpp index 998cd69985d3f8..f593158cb2f9fd 100644 --- a/src/coreclr/pal/src/file/directory.cpp +++ b/src/coreclr/pal/src/file/directory.cpp @@ -67,6 +67,13 @@ CreateDirectoryW( goto done; } + if (lpPathName == NULL) + { + ERROR("CreateDirectoryW called with NULL pathname!\n"); + dwLastError = ERROR_PATH_NOT_FOUND; + goto done; + } + /* translate the wide char lpPathName string to multibyte string */ if(0 == (mb_size = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpPathName, PAL_wcslen(lpPathName) + 1, 0))) { diff --git a/src/coreclr/pal/src/file/file.cpp b/src/coreclr/pal/src/file/file.cpp index 7f1a8da17ea05c..6990a1ad228fa8 100644 --- a/src/coreclr/pal/src/file/file.cpp +++ b/src/coreclr/pal/src/file/file.cpp @@ -828,11 +828,15 @@ CreateFileW( pThread = InternalGetCurrentThread(); - if (lpFileName != NULL) + if (lpFileName == NULL) { - length = (PAL_wcslen(lpFileName)+1) * MaxWCharToAcpLengthFactor; + ERROR("CreateFileW called with NULL filename\n"); + palError = ERROR_PATH_NOT_FOUND; + goto done; } + length = (PAL_wcslen(lpFileName)+1) * MaxWCharToAcpLengthFactor; + name = namePathString.OpenStringBuffer(length); if (NULL == name) { diff --git a/src/coreclr/utilcode/stacktrace.cpp b/src/coreclr/utilcode/stacktrace.cpp index dd2f07c0799fd6..3503b413b64e55 100644 --- a/src/coreclr/utilcode/stacktrace.cpp +++ b/src/coreclr/utilcode/stacktrace.cpp @@ -341,14 +341,13 @@ LPSTR FillSymbolSearchPathThrows(CQuickBytes &qb) #endif // Now we have a working buffer with a bunch of interesting stuff. Time - // to convert it to UTF-8 for the imagehlp api's. - LPCWSTR wszBuff = rcBuff.GetUnicode(); - size_t cchBuff = u16_strlen(wszBuff) + 1; - ch = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)wszBuff, cchBuff, 0); + // to convert it back to ansi for the imagehlp api's. Allocate the buffer + // 2x bigger to handle worst case for MBCS. + ch = ::WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, rcBuff, -1, 0, 0, 0, 0); LPSTR szRtn = (LPSTR) qb.AllocNoThrow(ch + 1); if (!szRtn) return NULL; - minipal_convert_utf16_to_utf8((const CHAR16_T*)wszBuff, cchBuff, szRtn, ch + 1, 0); + WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, rcBuff, -1, szRtn, ch+1, 0, 0); return (szRtn); } LPSTR FillSymbolSearchPath(CQuickBytes &qb) diff --git a/src/coreclr/vm/eventtrace_bulktype.cpp b/src/coreclr/vm/eventtrace_bulktype.cpp index 146d706078f23c..d22760eed533a5 100644 --- a/src/coreclr/vm/eventtrace_bulktype.cpp +++ b/src/coreclr/vm/eventtrace_bulktype.cpp @@ -465,14 +465,14 @@ void BulkStaticsLogger::WriteEntry(AppDomain *domain, Object **address, Object * ULONGLONG th = (ULONGLONG)typeHandle.AsTAddr(); ETW::TypeSystemLog::LogTypeAndParametersIfNecessary(m_typeLogger, th, ETW::TypeSystemLog::kTypeLogBehaviorTakeLockAndLogIfFirstTime); - // We should have at least 512 characters remaining in the buffer here. + // We should have room for an entry with the longest field name in the buffer here. int remaining = kMaxBytesValues - m_used; - _ASSERTE(kMaxBytesValues - m_used > 512); + _ASSERTE(remaining >= EventStaticEntry::MaxEntrySize()); int len = EventStaticEntry::WriteEntry(m_buffer + m_used, remaining, (ULONGLONG)address, (ULONGLONG)obj, th, 0, fieldDesc); - // 512 bytes was not enough buffer? This shouldn't happen, so we'll skip emitting the + // There was not enough buffer? This shouldn't happen, so we'll skip emitting the // event on error. if (len > 0) { @@ -481,7 +481,7 @@ void BulkStaticsLogger::WriteEntry(AppDomain *domain, Object **address, Object * } // When we are close to running out of buffer, emit the event. - if (kMaxBytesValues - m_used < 512) + if (kMaxBytesValues - m_used < EventStaticEntry::MaxEntrySize()) FireBulkStaticsEvent(); } diff --git a/src/coreclr/vm/eventtracepriv.h b/src/coreclr/vm/eventtracepriv.h index cbc6da8a59dfba..11927c08144657 100644 --- a/src/coreclr/vm/eventtracepriv.h +++ b/src/coreclr/vm/eventtracepriv.h @@ -104,6 +104,13 @@ struct EventStaticEntry ULONG Flags; WCHAR Name[0]; + // The size of an entry with the longest field name we emit (255 characters). Longer names are emitted as empty strings. + static int MaxEntrySize() + { + LIMITED_METHOD_CONTRACT; + return (int)(sizeof(EventStaticEntry) + 256 * sizeof(WCHAR)); + } + // Writes one EventStaticEntry to the buffer specified by ptr. Since we don't actually know how large the event will be, // this write may fail if the remaining buffer is not large enough. This function returns the number of bytes written // on success (return is >= 0), and -1 on failure. If we return -1, the caller is expected to flush the current buffer @@ -130,7 +137,7 @@ struct EventStaticEntry if (len <= 0) { // We will only emit names for fields which are up to 255 characters (and also don't fit in the buffer). - if (sizeRemaining < 256) + if (sizeRemaining < MaxEntrySize()) return -1; // nothing written, insufficient buffer. Flush and try again. // If the name is larger than 255, just emit an empty string. From 7a98ce93619dea57474117c0eed1fc9246957e60 Mon Sep 17 00:00:00 2001 From: am11 <3840695+am11@users.noreply.github.com> Date: Sat, 7 Nov 2026 18:49:00 +0200 Subject: [PATCH 08/13] Fix Unix ildasm path conversion after MultiByteToWideChar removal Co-authored-by: Cursor --- src/coreclr/ildasm/windasm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/ildasm/windasm.cpp b/src/coreclr/ildasm/windasm.cpp index fdd4901a6dd05b..26cf2baae862e7 100644 --- a/src/coreclr/ildasm/windasm.cpp +++ b/src/coreclr/ildasm/windasm.cpp @@ -136,7 +136,7 @@ char* EqualOrColon(_In_ __nullterminated char* szArg) void GetInputFileFullPath() { #ifdef TARGET_UNIX - MultiByteToWideChar(g_uConsoleCP, 0, g_szInputFile, -1, g_wszFullInputFile, MAX_PATH + 1); + minipal_convert_utf8_to_utf16(g_szInputFile, strlen(g_szInputFile) + 1, (CHAR16_T*)g_wszFullInputFile, MAX_PATH + 1, 0); #else // We need the input file's full path to make uses of it later, despite changing CurrentDirectory From 0eaf221ebe9d9c3f1dee85f6526ebe4da59119f2 Mon Sep 17 00:00:00 2001 From: am11 <3840695+am11@users.noreply.github.com> Date: Sat, 7 Nov 2026 18:54:08 +0200 Subject: [PATCH 09/13] Replace verbMerge::ConvertToUtf8 with the shared std::string helper Co-authored-by: Cursor --- src/coreclr/tools/superpmi/mcs/verbmerge.cpp | 51 +++++++------------- src/coreclr/tools/superpmi/mcs/verbmerge.h | 1 - 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/src/coreclr/tools/superpmi/mcs/verbmerge.cpp b/src/coreclr/tools/superpmi/mcs/verbmerge.cpp index a34e2ff35c9593..60e1527b8f59cf 100644 --- a/src/coreclr/tools/superpmi/mcs/verbmerge.cpp +++ b/src/coreclr/tools/superpmi/mcs/verbmerge.cpp @@ -45,15 +45,6 @@ LPWSTR verbMerge::MergePathStrings(LPCWSTR dir, LPCWSTR file) return newpath; } -char* verbMerge::ConvertToUtf8(LPCWSTR wstr) -{ - size_t length = u16_strlen(wstr) + 1; - size_t sizeNeeded = minipal_get_length_utf16_to_utf8((const CHAR16_T*)wstr, length, 0); - char* encodedStr = new char[sizeNeeded]; - minipal_convert_utf16_to_utf8((const CHAR16_T*)wstr, length, encodedStr, sizeNeeded, 0); - return encodedStr; -} - WCHAR* verbMerge::ConvertFromUtf8(LPCSTR str) { size_t length = strlen(str) + 1; @@ -74,20 +65,20 @@ int verbMerge::AppendFileRaw(FILE* hFileOut, LPCWSTR fileFullPath, unsigned char { int result = 0; // default to zero == success - char* fileNameAsChar = ConvertToUtf8(fileFullPath); - LogInfo("Appending file '%s'", fileNameAsChar); + std::string fileNameAsChar = ConvertToUtf8(fileFullPath); + LogInfo("Appending file '%s'", fileNameAsChar.c_str()); FILE* hFileIn; if (u16_fopen_s(&hFileIn, fileFullPath, W("rb")) != 0) { - LogError("Failed to open input file '%s'. errno=%d", fileNameAsChar, errno); + LogError("Failed to open input file '%s'. errno=%d", fileNameAsChar.c_str(), errno); return -1; } int64_t fileSize = fgetsize(hFileIn); if (fileSize < 0) { - LogError("fgetsize on '%s' failed. errno=%d", fileNameAsChar, errno); + LogError("fgetsize on '%s' failed. errno=%d", fileNameAsChar.c_str(), errno); result = -1; goto CLEAN_UP; } @@ -97,7 +88,7 @@ int verbMerge::AppendFileRaw(FILE* hFileOut, LPCWSTR fileFullPath, unsigned char size_t bytesRead = fread(buffer, 1, bufferSize, hFileIn); if (ferror(hFileIn)) { - LogError("Failed to read '%s' from offset %lld. errno=%d", fileNameAsChar, offset, errno); + LogError("Failed to read '%s' from offset %lld. errno=%d", fileNameAsChar.c_str(), offset, errno); result = -1; goto CLEAN_UP; } @@ -112,8 +103,6 @@ int verbMerge::AppendFileRaw(FILE* hFileOut, LPCWSTR fileFullPath, unsigned char CLEAN_UP: - delete[] fileNameAsChar; - if (fclose(hFileIn) != 0) { LogError("fclose failed. errno=%d", errno); @@ -135,11 +124,10 @@ int verbMerge::AppendFile(FILE* hFileOut, LPCWSTR fileFullPath, bool dedup, unsi if (dedup) { - // Need to conver the fileFullPath to non-Unicode. - char* fileFullPathAsChar = ConvertToUtf8(fileFullPath); - LogInfo("Appending file '%s'", fileFullPathAsChar); - bool ok = m_removeDups.CopyAndRemoveDups(fileFullPathAsChar, hFileOut); - delete[] fileFullPathAsChar; + // Need to convert the fileFullPath to non-Unicode. + std::string fileFullPathAsChar = ConvertToUtf8(fileFullPath); + LogInfo("Appending file '%s'", fileFullPathAsChar.c_str()); + bool ok = m_removeDups.CopyAndRemoveDups(fileFullPathAsChar.c_str(), hFileOut); if (!ok) { LogError("Failed to remove dups"); @@ -268,8 +256,8 @@ int verbMerge::FilterDirectory(LPCWSTR dir, // NOTE: this function only works on Windows 7 and later. #ifdef TARGET_UNIX - std::string dirUtf8 = ::ConvertToUtf8(dir); - std::string searchPatternUtf8 = ::ConvertToUtf8(searchPattern); + std::string dirUtf8 = ConvertToUtf8(dir); + std::string searchPatternUtf8 = ConvertToUtf8(searchPattern); DIR* pDir = opendir(dirUtf8.c_str()); if (pDir != nullptr) @@ -343,7 +331,7 @@ int verbMerge::FilterDirectory(LPCWSTR dir, } else { - std::string searchPatternUtf8 = ::ConvertToUtf8(searchPattern); + std::string searchPatternUtf8 = ConvertToUtf8(searchPattern); LogError("Failed to find pattern '%s'. errno=%d", searchPatternUtf8.c_str(), errno); result = -1; } @@ -371,7 +359,7 @@ int verbMerge::FilterDirectory(LPCWSTR dir, } else { - std::string searchPatternUtf8 = ::ConvertToUtf8(searchPattern); + std::string searchPatternUtf8 = ConvertToUtf8(searchPattern); LogError("Failed to find pattern '%s'. GetLastError()=%u", searchPatternUtf8.c_str(), GetLastError()); result = -1; } @@ -503,26 +491,23 @@ int verbMerge::AppendAllInDir(FILE* hFileOut, #else // TARGET_WINDOWS struct stat fileStat; - char *fileFullPathUtf8 = ConvertToUtf8(fileFullPath); - int st = stat(fileFullPathUtf8, &fileStat); + std::string fileFullPathUtf8 = ConvertToUtf8(fileFullPath); + int st = stat(fileFullPathUtf8.c_str(), &fileStat); if (st != 0) { - LogError("Failed to stat file '%s'. errno=%d", fileFullPathUtf8, errno); + LogError("Failed to stat file '%s'. errno=%d", fileFullPathUtf8.c_str(), errno); result = -1; delete[] fileFullPath; - delete[] fileFullPathUtf8; goto CLEAN_UP; } - delete[] fileFullPathUtf8; uint64_t fileSize = fileStat.st_size; #endif // TARGET_WINDOWS // Is it zero length? If so, skip it. if (fileSize == 0) { - char* fileFullPathAsChar = ConvertToUtf8(fileFullPath); - LogInfo("Skipping zero-length file '%s'", fileFullPathAsChar); - delete[] fileFullPathAsChar; + std::string fileFullPathAsChar = ConvertToUtf8(fileFullPath); + LogInfo("Skipping zero-length file '%s'", fileFullPathAsChar.c_str()); } else { diff --git a/src/coreclr/tools/superpmi/mcs/verbmerge.h b/src/coreclr/tools/superpmi/mcs/verbmerge.h index 7924cf031074b8..c02a4bd4958d17 100644 --- a/src/coreclr/tools/superpmi/mcs/verbmerge.h +++ b/src/coreclr/tools/superpmi/mcs/verbmerge.h @@ -80,7 +80,6 @@ class verbMerge static LPWSTR MergePathStrings(LPCWSTR dir, LPCWSTR file); - static char* ConvertToUtf8(LPCWSTR wstr); static WCHAR* ConvertFromUtf8(LPCSTR str); static int AppendFileRaw(FILE* hFileOut, LPCWSTR fileFullPath, unsigned char* buffer, size_t bufferSize); From 6ad51e817dbc6408c54d6cd76961f94d13f714ce Mon Sep 17 00:00:00 2001 From: am11 <3840695+am11@users.noreply.github.com> Date: Sat, 7 Nov 2026 21:59:13 +0200 Subject: [PATCH 10/13] Remove unused and CRT-passthrough PAL tests Drop palsuite coverage for APIs that no longer exist (IsBad*, Sleep, CompareString*, GetLocaleInfoW, LoadLibraryA, PAL_RegisterLibraryW) and for plain C-runtime functions that do not go through the PAL. Co-authored-by: Cursor --- src/coreclr/pal/tests/palsuite/CMakeLists.txt | 58 ----- .../pal/tests/palsuite/DisabledTests.txt | 2 - .../c_runtime/_alloca/test1/test1.cpp | 61 ----- .../palsuite/c_runtime/_rotl/test1/test1.cpp | 54 ---- .../palsuite/c_runtime/_rotr/test1/test1.cpp | 59 ----- .../palsuite/c_runtime/atof/test1/test1.cpp | 74 ------ .../palsuite/c_runtime/atoi/test1/test1.cpp | 85 ------- .../c_runtime/isalnum/test1/test1.cpp | 87 ------- .../c_runtime/isalpha/test1/test1.cpp | 85 ------- .../c_runtime/isdigit/test1/test1.cpp | 46 ---- .../c_runtime/isprint/test1/isprint.cpp | 41 ---- .../c_runtime/isprint/test2/test2.cpp | 58 ----- .../c_runtime/isspace/test1/test1.cpp | 81 ------ .../c_runtime/iswdigit/test1/test1.cpp | 68 ------ .../c_runtime/iswprint/test1/test1.cpp | 58 ----- .../c_runtime/iswspace/test1/test1.cpp | 77 ------ .../c_runtime/iswupper/test1/test1.cpp | 90 ------- .../c_runtime/isxdigit/test1/test1.cpp | 54 ---- .../palsuite/c_runtime/llabs/test1/test1.cpp | 64 ----- .../palsuite/c_runtime/memchr/test1/test1.cpp | 121 --------- .../palsuite/c_runtime/memcmp/test1/test1.cpp | 56 ----- .../c_runtime/memmove/test1/test1.cpp | 115 --------- .../palsuite/c_runtime/memset/test1/test1.cpp | 59 ----- .../palsuite/c_runtime/strcat/test1/test1.cpp | 65 ----- .../palsuite/c_runtime/strchr/test1/test1.cpp | 85 ------- .../palsuite/c_runtime/strcmp/test1/test1.cpp | 72 ------ .../palsuite/c_runtime/strcpy/test1/test1.cpp | 50 ---- .../palsuite/c_runtime/strlen/test1/test1.cpp | 32 --- .../c_runtime/strncat/test1/test1.cpp | 76 ------ .../c_runtime/strncmp/test1/test1.cpp | 78 ------ .../c_runtime/strncpy/test1/test1.cpp | 84 ------- .../c_runtime/strpbrk/test1/test1.cpp | 84 ------- .../c_runtime/strrchr/test1/test1.cpp | 54 ---- .../palsuite/c_runtime/strstr/test1/test1.cpp | 82 ------- .../c_runtime/tolower/test1/test1.cpp | 78 ------ .../c_runtime/toupper/test1/test1.cpp | 63 ----- .../c_runtime/towlower/test1/test1.cpp | 78 ------ .../c_runtime/towupper/test1/test1.cpp | 64 ----- .../pal/tests/palsuite/compilableTests.txt | 44 ---- .../tests/palsuite/compileDisabledTests.txt | 12 - .../LoadLibraryA/test1/LoadLibraryA.cpp | 52 ---- .../LoadLibraryA/test2/LoadLibraryA.cpp | 51 ---- .../LoadLibraryA/test3/loadlibrarya.cpp | 39 --- .../LoadLibraryA/test5/loadlibrarya.cpp | 66 ----- .../loader/LoadLibraryA/test6/dlltest.cpp | 71 ------ .../LoadLibraryA/test6/loadlibrarya.cpp | 169 ------------- .../LoadLibraryA/test7/LoadLibraryA.cpp | 82 ------- .../loader/LoadLibraryA/test8/dlltest.cpp | 71 ------ .../LoadLibraryA/test8/loadlibrarya.cpp | 231 ------------------ .../CompareStringA/test1/test1.cpp | 98 -------- .../CompareStringW/test1/test1.cpp | 98 -------- .../GetLocaleInfoW/test1/test1.cpp | 86 ------- .../GetLocaleInfoW/test2/test2.cpp | 50 ---- .../IsBadCodePtr/test1/test1.cpp | 59 ----- .../miscellaneous/IsBadReadPtr/test1/test.cpp | 111 --------- .../IsBadWritePtr/test1/test.cpp | 81 ------ .../IsBadWritePtr/test2/test2.cpp | 79 ------ .../IsBadWritePtr/test3/test3.cpp | 46 ---- ...AL_RegisterLibraryW_UnregisterLibraryW.cpp | 63 ----- .../test2_neg/reg_unreg_libraryw_neg.cpp | 61 ----- .../pal/tests/palsuite/paltestlist.txt | 37 --- .../palsuite/paltestlist_to_be_reviewed.txt | 16 -- .../palsuite/threading/Sleep/test1/Sleep.cpp | 72 ------ .../palsuite/threading/Sleep/test2/sleep.cpp | 64 ----- 64 files changed, 4507 deletions(-) delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/_alloca/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/_rotl/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/_rotr/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/atof/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/atoi/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/isalnum/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/isalpha/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/isdigit/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/isprint/test1/isprint.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/isprint/test2/test2.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/isspace/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/iswdigit/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/iswprint/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/iswspace/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/iswupper/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/isxdigit/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/llabs/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/memchr/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/memcmp/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/memmove/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/memset/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/strcat/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/strchr/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/strcmp/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/strcpy/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/strlen/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/strncat/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/strncmp/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/strncpy/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/strpbrk/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/strrchr/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/strstr/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/tolower/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/toupper/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/towlower/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/c_runtime/towupper/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test1/LoadLibraryA.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test2/LoadLibraryA.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test3/loadlibrarya.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test5/loadlibrarya.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test6/loadlibrarya.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test7/LoadLibraryA.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test8/loadlibrarya.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/locale_info/CompareStringA/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/locale_info/CompareStringW/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/locale_info/GetLocaleInfoW/test2/test2.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/test1.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/test.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/test.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/test2.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/test3.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/PAL_RegisterLibraryW_UnregisterLibraryW.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/reg_unreg_libraryw_neg.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/threading/Sleep/test1/Sleep.cpp delete mode 100644 src/coreclr/pal/tests/palsuite/threading/Sleep/test2/sleep.cpp diff --git a/src/coreclr/pal/tests/palsuite/CMakeLists.txt b/src/coreclr/pal/tests/palsuite/CMakeLists.txt index d003e1e7478d9f..f4c57af54c0ca7 100644 --- a/src/coreclr/pal/tests/palsuite/CMakeLists.txt +++ b/src/coreclr/pal/tests/palsuite/CMakeLists.txt @@ -38,24 +38,6 @@ add_executable_clr(paltests EXCLUDE_FROM_ALL paltests.cpp common/palsuite.cpp - c_runtime/atof/test1/test1.cpp - c_runtime/atoi/test1/test1.cpp - c_runtime/isalnum/test1/test1.cpp - c_runtime/isalpha/test1/test1.cpp - c_runtime/isdigit/test1/test1.cpp - c_runtime/isprint/test1/isprint.cpp - c_runtime/isprint/test2/test2.cpp - c_runtime/isspace/test1/test1.cpp - c_runtime/iswdigit/test1/test1.cpp - #c_runtime/iswprint/test1/test1.cpp - c_runtime/iswspace/test1/test1.cpp - c_runtime/iswupper/test1/test1.cpp - c_runtime/isxdigit/test1/test1.cpp - c_runtime/llabs/test1/test1.cpp - c_runtime/memchr/test1/test1.cpp - c_runtime/memcmp/test1/test1.cpp - c_runtime/memmove/test1/test1.cpp - c_runtime/memset/test1/test1.cpp c_runtime/sscanf_s/test1/test1.cpp c_runtime/sscanf_s/test10/test10.cpp c_runtime/sscanf_s/test11/test11.cpp @@ -73,21 +55,6 @@ add_executable_clr(paltests c_runtime/sscanf_s/test7/test7.cpp c_runtime/sscanf_s/test8/test8.cpp c_runtime/sscanf_s/test9/test9.cpp - c_runtime/strcat/test1/test1.cpp - c_runtime/strchr/test1/test1.cpp - c_runtime/strcmp/test1/test1.cpp - c_runtime/strcpy/test1/test1.cpp - c_runtime/strlen/test1/test1.cpp - c_runtime/strncat/test1/test1.cpp - c_runtime/strncmp/test1/test1.cpp - c_runtime/strncpy/test1/test1.cpp - c_runtime/strpbrk/test1/test1.cpp - c_runtime/strrchr/test1/test1.cpp - c_runtime/strstr/test1/test1.cpp - c_runtime/tolower/test1/test1.cpp - c_runtime/toupper/test1/test1.cpp - c_runtime/towlower/test1/test1.cpp - c_runtime/towupper/test1/test1.cpp c_runtime/wcscat/test1/test1.cpp c_runtime/wcschr/test1/test1.cpp c_runtime/wcscmp/test1/test1.cpp @@ -105,9 +72,6 @@ add_executable_clr(paltests c_runtime/wcstoul/test4/test4.cpp c_runtime/wcstoul/test5/test5.cpp c_runtime/wcstoul/test6/test6.cpp - c_runtime/_alloca/test1/test1.cpp - c_runtime/_rotl/test1/test1.cpp - c_runtime/_rotr/test1/test1.cpp c_runtime/_vsnprintf_s/test1/test1.cpp c_runtime/_vsnprintf_s/test10/test10.cpp c_runtime/_vsnprintf_s/test11/test11.cpp @@ -166,23 +130,10 @@ add_executable_clr(paltests # filemapping_memmgt/GetProcAddress/test2/testlib.cpp filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/ProbeMemory_neg.cpp filemapping_memmgt/ProbeMemory/test1/ProbeMemory.cpp - loader/LoadLibraryA/test1/LoadLibraryA.cpp - loader/LoadLibraryA/test2/LoadLibraryA.cpp - loader/LoadLibraryA/test3/loadlibrarya.cpp - loader/LoadLibraryA/test5/loadlibrarya.cpp - #loader/LoadLibraryA/test6/dlltest.cpp - #loader/LoadLibraryA/test6/loadlibrarya.cpp - loader/LoadLibraryA/test7/LoadLibraryA.cpp - #loader/LoadLibraryA/test8/dlltest.cpp - #loader/LoadLibraryA/test8/loadlibrarya.cpp loader/LoadLibraryW/test1/LoadLibraryW.cpp loader/LoadLibraryW/test2/loadlibraryw.cpp loader/LoadLibraryW/test3/loadlibraryw.cpp loader/LoadLibraryW/test5/loadlibraryw.cpp - #locale_info/CompareStringA/test1/test1.cpp - #locale_info/CompareStringW/test1/test1.cpp - #locale_info/GetLocaleInfoW/test1/test1.cpp - #locale_info/GetLocaleInfoW/test2/test2.cpp miscellaneous/CloseHandle/test2/test.cpp miscellaneous/FlushInstructionCache/test1/test1.cpp miscellaneous/FormatMessageW/test1/test.cpp @@ -225,11 +176,6 @@ add_executable_clr(paltests miscellaneous/InterlockedIncrement/test2/test.cpp miscellaneous/InterlockedIncrement64/test1/test.cpp miscellaneous/InterlockedIncrement64/test2/test.cpp - #miscellaneous/IsBadCodePtr/test1/test1.cpp - #miscellaneous/IsBadReadPtr/test1/test.cpp - #miscellaneous/IsBadWritePtr/test1/test.cpp - #miscellaneous/IsBadWritePtr/test2/test2.cpp - #miscellaneous/IsBadWritePtr/test3/test3.cpp miscellaneous/SetEnvironmentVariableA/test1/test1.cpp miscellaneous/SetEnvironmentVariableA/test2/test2.cpp miscellaneous/SetEnvironmentVariableA/test3/test3.cpp @@ -241,8 +187,6 @@ add_executable_clr(paltests miscellaneous/SetLastError/test1/test.cpp pal_specific/PAL_Initialize_Terminate/test1/PAL_Initialize_Terminate.cpp pal_specific/PAL_Initialize_Terminate/test2/pal_initialize_twice.cpp -# pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/PAL_RegisterLibraryW_UnregisterLibraryW.cpp -# pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/reg_unreg_libraryw_neg.cpp samples/test1/test.cpp samples/test2/test.cpp threading/CreateThread/test1/test1.cpp @@ -263,8 +207,6 @@ add_executable_clr(paltests threading/QueryThreadCycleTime/test1/test1.cpp threading/ResumeThread/test1/test1.cpp threading/RuntimeEvent/test1/test1.cpp - threading/Sleep/test1/Sleep.cpp - threading/Sleep/test2/sleep.cpp threading/SwitchToThread/test1/test1.cpp threading/TerminateProcess/test1/TerminateProcess.cpp threading/ThreadPriority/test1/ThreadPriority.cpp diff --git a/src/coreclr/pal/tests/palsuite/DisabledTests.txt b/src/coreclr/pal/tests/palsuite/DisabledTests.txt index 6b665948ce27e1..e5d3f730249cef 100644 --- a/src/coreclr/pal/tests/palsuite/DisabledTests.txt +++ b/src/coreclr/pal/tests/palsuite/DisabledTests.txt @@ -15,13 +15,11 @@ The above testcases were disabled in the palsuite, because they depend heavily o WaitForDebugEvent,DebugActiveProcess and ContinueDebugEvent, where these api's have been removed from the PAL. -locale_info/getcpinfo/test2: ======================================= This test will be useful in future versions for testing various languages (code pages). Currently only U.S. English (tested by - test1) is supported. -locale_info/getcpinfo/test3: ======================================= This test will be useful in future versions for testing various languages (code pages). Currently only U.S. English (tested by - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/_alloca/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/_alloca/test1/test1.cpp deleted file mode 100644 index d11b65e99dce05..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/_alloca/test1/test1.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Checks that _alloca allocates memory, and that the memory is -** readable and writeable. -** -** -**==========================================================================*/ - -#include - -PALTEST(c_runtime__alloca_test1_paltest_alloca_test1, "c_runtime/_alloca/test1/paltest_alloca_test1") -{ - - char *testA = NULL; - int i = 0; - - /* - * Initialize the PAL and return FAIL if this fails - */ - if (0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - - /* check that _alloca really gives us addressable memory */ - testA = (char *)_alloca(20 * sizeof(char)); - if (testA == NULL) - { - Fail ("The call to _alloca failed\n"); - } - - memset(testA, 'a', 20); - - for (i = 0; i < 20; i++) - { - if (testA[i] != 'a') - { - Fail ("The memory returned by _alloca doesn't seem to be" - " properly allocated\n"); - } - } - - PAL_Terminate(); - return PASS; -} - - - - - - - - - - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/_rotl/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/_rotl/test1/test1.cpp deleted file mode 100644 index 52f321ec97064f..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/_rotl/test1/test1.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c (_rotl) -** -** Purpose: Tests the PAL implementation of the _rotl function. -** The _rotl function rotates the unsigned value. _rotl -** rotates the value left and "wraps" bits rotated off -** one end of value to the other end. -** This test compares the result to a previously determined -** value. -** -** -** -**===================================================================*/ -#include - -PALTEST(c_runtime__rotl_test1_paltest_rotl_test1, "c_runtime/_rotl/test1/paltest_rotl_test1") -{ - unsigned results = 0; - int i,j; - - unsigned hTestNums[5][8] = { - {0x00ff, 0x01fe, 0x03fc, 0x07f8, 0x0ff0, 0x1fe0, 0x3fc0, 0x7f80}, - {0x0055, 0x00aa, 0x0154, 0x02a8, 0x0550, 0x0aa0, 0x1540, 0x2a80}, - {0x0099, 0x0132, 0x0264, 0x04c8, 0x0990, 0x1320, 0x2640, 0x4c80}, - {0x0036, 0x006c, 0x00d8, 0x01b0, 0x0360, 0x06c0, 0x0d80, 0x1b00}, - {0x008f, 0x011e, 0x023c, 0x0478, 0x08f0, 0x11e0, 0x23c0, 0x4780}}; - - if ((PAL_Initialize(argc, argv)) != 0) - { - return (FAIL); - } - - /*Loop through expected test results*/ - for (j = 0; j <= 4; j++) - { - for(i = 1; i <= 7; i++) - { - results = _rotl(hTestNums[j][0], i); - if (results != hTestNums[j][i]) - { - Fail("ERROR: \"0x%4.4x\" rotated bits to the left %d times" - " gave \"0x%4.4x\", expected \"0x%4.4x\"\n", - hTestNums[j][0], i, results, hTestNums[j][i]) ; - } - } - } - - PAL_Terminate(); - return (PASS); -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/_rotr/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/_rotr/test1/test1.cpp deleted file mode 100644 index 2f753c56b6c174..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/_rotr/test1/test1.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c (_rotr) -** -** Purpose: Tests the PAL implementation of the _rotr function. -** The _rotr function rotates the unsigned value. _rotr -** rotates the value right and "wraps" bits rotated off -** one end of value to the other end. -** This test compares the result to a previously -** determined value. -** -** -**===================================================================*/ -#include - -PALTEST(c_runtime__rotr_test1_paltest_rotr_test1, "c_runtime/_rotr/test1/paltest_rotr_test1") -{ - unsigned results = 0; - int i,j; - - unsigned hTestNums[5][8] = { - {0x00ff, 0x8000007f, 0xc000003f, 0xe000001f, - 0xf000000f, 0xf8000007, 0xfc000003, 0xfe000001}, - {0x0055, 0x8000002a, 0x40000015, 0xa000000a, - 0x50000005, 0xa8000002, 0x54000001, 0xaa000000}, - {0x0099, 0x8000004c, 0x40000026, 0x20000013, - 0x90000009, 0xc8000004, 0x64000002, 0x32000001}, - {0x0036, 0x001b, 0x8000000d, 0xc0000006, - 0x60000003, 0xb0000001, 0xd8000000, 0x6c000000}, - {0x008f, 0x80000047, 0xc0000023, 0xe0000011, - 0xf0000008, 0x78000004, 0x3c000002 ,0x1e000001}}; - - - if ((PAL_Initialize(argc, argv)) != 0) - { - return (FAIL); - } - - /*Loop through expected test results*/ - for (j = 0; j <= 4; j++) - { - for(i = 1; i <= 7; i++) - { - results = _rotr(hTestNums[j][0], i); - if (results != hTestNums[j][i]) - { - Fail("ERROR: \"0x%4.4x\" rotated bits to the left %d times" - " gave \"0x%4.4x\", expected \"0x%4.4x\"\n", - hTestNums[j][0], i, results, hTestNums[j][i]) ; - } - } - } - - PAL_Terminate(); - return (PASS); -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/atof/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/atof/test1/test1.cpp deleted file mode 100644 index 6d8becb3d955b2..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/atof/test1/test1.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Passes to atof() a series of strings containing floats, -** checking that each one is correctly extracted. -** -** -**==========================================================================*/ - -#include -#include - -struct testCase -{ - float fvalue; - char avalue[20]; -}; - -PALTEST(c_runtime_atof_test1_paltest_atof_test1, "c_runtime/atof/test1/paltest_atof_test1") -{ - int i = 0; - double f = 0; - struct testCase testCases[] = - { - {1234, "1234"}, - {-1234, "-1234"}, - {1234e-5, "1234e-5"}, - {1234e+5, "1234e+5"}, - {1234e5, "1234E5"}, - {1234.567e-8, "1234.567e-8"}, - {1234.567e-8, " 1234.567e-8 foo"}, - {0,"a12"} - }; - - /* - * Initialize the PAL and return FAIL if this fails - */ - if (0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - for(i = 0; i < sizeof(testCases) / sizeof(struct testCase); i++) - { - /*Convert the string to a float.*/ - f = atof(testCases[i].avalue); - double result = f - testCases[i].fvalue; - - if (fabs(result) > FLT_EPSILON) - { - Fail ("atof misinterpreted \"%s\" as %g instead of %g. result %g fabs %g\n", - testCases[i].avalue, f, testCases[i].fvalue, result, fabs(result)); - } - } - PAL_Terminate(); - return PASS; -} - - - - - - - - - - - - - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/atoi/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/atoi/test1/test1.cpp deleted file mode 100644 index 3137bf903e6824..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/atoi/test1/test1.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests the PAL implementation of the atoi function. -** Check to ensure that the different ints (normal, -** negative, decimal,exponent), all work as expected with -** this function. -** -** -**===================================================================*/ - -#include - - -struct testCase -{ - int IntValue; - char avalue[20]; -}; - -PALTEST(c_runtime_atoi_test1_paltest_atoi_test1, "c_runtime/atoi/test1/paltest_atoi_test1") -{ - - int result=0; - int i=0; - - struct testCase testCases[] = - { - {1234, "1234"}, - {-1234, "-1234"}, - {1234, "1234.44"}, - {1234, "1234e-5"}, - {1234, "1234e+5"}, - {1234, "1234E5"}, - {1234, "1234.657e-8"}, - {1234567, " 1234567e-8 foo"}, - {0, "aaa 32 test"} - }; - - /* - * Initialize the PAL and return FAIL if this fails - */ - if (0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - /* Loop through each case. Convert the string to an int - and then compare to ensure that it is the correct value. - */ - - for(i = 0; i < sizeof(testCases) / sizeof(struct testCase); i++) - { - /*Convert the string to an int.*/ - result = atoi(testCases[i].avalue); - - if (testCases[i].IntValue != result) - { - Fail("ERROR: atoi misinterpreted \"%s\" as %i instead of %i.\n" - , testCases[i].avalue, result, testCases[i].IntValue); - } - - } - - - PAL_Terminate(); - return PASS; -} - - - - - - - - - - - - - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/isalnum/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/isalnum/test1/test1.cpp deleted file mode 100644 index b7ec330ae94769..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/isalnum/test1/test1.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests the PAL implementation of the isalnum function -** Check that a number of characters return the correct -** values for whether they are alpha/numeric or not. -** -** -**===================================================================*/ - -#include - - -struct testCase -{ - int CorrectResult; - int character; -}; - -PALTEST(c_runtime_isalnum_test1_paltest_isalnum_test1, "c_runtime/isalnum/test1/paltest_isalnum_test1") -{ - - int result; - int i; - - struct testCase testCases[] = - { - {1, 'a'}, - {1, 'z'}, - {1, 'B'}, - {1, '5'}, - {1, '0'}, - {0, '?'}, - {0, 230} - }; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - /* Loop through each case. Check to see if each is alpha/numeric or - not. - */ - - for(i = 0; i < sizeof(testCases) / sizeof(struct testCase); i++) - { - - result = isalnum(testCases[i].character); - - /* The return value is 'non-zero' for success. This if condition - * will still work if that non-zero isn't just 1 - */ - if ( ((testCases[i].CorrectResult == 1) && (result == 0)) || - ( (testCases[i].CorrectResult == 0) && (result != 0) )) - { - Fail("ERROR: isalnum returned %i instead of %i for character " - " %c.\n", - result, - testCases[i].CorrectResult, - testCases[i].character); - } - - } - - - PAL_Terminate(); - return PASS; -} - - - - - - - - - - - - - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/isalpha/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/isalpha/test1/test1.cpp deleted file mode 100644 index 581f5d3e277ad8..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/isalpha/test1/test1.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests the PAL implementation of the isalpha function -** Check that a number of characters return the correct -** values for whether they are alpha or not. -** -** -**===================================================================*/ - -#include - -struct testCase -{ - int CorrectResult; - int character; -}; - -PALTEST(c_runtime_isalpha_test1_paltest_isalpha_test1, "c_runtime/isalpha/test1/paltest_isalpha_test1") -{ - - int result; - int i; - - struct testCase testCases[] = - { - {1, 'a'}, - {1, 'z'}, - {1, 'B'}, - {0, '5'}, - {0, '?'}, - {0, 230} - }; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - /* Loop through each case. Check to see if each is alpha or - not. - */ - - for(i = 0; i < sizeof(testCases) / sizeof(struct testCase); i++) - { - - result = isalpha(testCases[i].character); - - /* The return value is 'non-zero' for success. This if condition - * will still work if that non-zero isn't just 1 - */ - if ( ((testCases[i].CorrectResult == 1) && (result == 0)) || - ( (testCases[i].CorrectResult == 0) && (result != 0) )) - { - Fail("ERROR: isalpha returned %i instead of %i for character " - "%c.\n", - result, - testCases[i].CorrectResult, - testCases[i].character); - } - - } - - - PAL_Terminate(); - return PASS; -} - - - - - - - - - - - - - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/isdigit/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/isdigit/test1/test1.cpp deleted file mode 100644 index d84029f9322d14..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/isdigit/test1/test1.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Checks every character against the known range of digits. -** -** -**==========================================================================*/ - - -#include - -PALTEST(c_runtime_isdigit_test1_paltest_isdigit_test1, "c_runtime/isdigit/test1/paltest_isdigit_test1") -{ - int i; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - for (i=0; i<256; i++) - { - if (isdigit(i)) - { - if (i < '0' || i > '9') - { - Fail("ERROR: isdigit returned true for '%c' (%d)!\n", i, i); - } - } - else - { - if (i >= '0' && i <= '9') - { - Fail("ERROR: isdigit returned false for '%c' (%d)!\n", i, i); - } - } - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/isprint/test1/isprint.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/isprint/test1/isprint.cpp deleted file mode 100644 index 0d3f0618024c6b..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/isprint/test1/isprint.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================= -** -** Source: isprint.c -** -** Purpose: Positive test the isprint API. -** Call isprint to test if a character is printable -** -** -**============================================================*/ -#include - -PALTEST(c_runtime_isprint_test1_paltest_isprint_test1, "c_runtime/isprint/test1/paltest_isprint_test1") -{ - int err; - int index; - - /*Initialize the PAL environment*/ - err = PAL_Initialize(argc, argv); - if(0 != err) - { - return FAIL; - } - - /*check if the character is printable*/ - for(index = 0x20; index<=0x7E;index++) - { - err = isprint(index); - if(0 == err) - { - Fail("\nFailed to call isprint API to check " - "printable character from 0x20 to 0x7E!\n"); - } - } - - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/isprint/test2/test2.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/isprint/test2/test2.cpp deleted file mode 100644 index 9871c1d221a66b..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/isprint/test2/test2.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================= -** -** Source: isprint.c -** -** Purpose: Negative test for the isprint API. Call isprint -** to test if out of range characters are -** not printable. -** -** -**============================================================*/ -#include - -PALTEST(c_runtime_isprint_test2_paltest_isprint_test2, "c_runtime/isprint/test2/paltest_isprint_test2") -{ - int err; - - /*Initialize the PAL environment*/ - err = PAL_Initialize(argc, argv); - if(0 != err) - { - return FAIL; - } - - /*check that function fails for values that are not printable*/ - err = isprint(0x15); - if(err) - { - Fail("\nSucceeded when it should have failed because 0x15 " - "is not in the range of printable characters\n"); - } - - err = isprint(0xAA); - if(err) - { - Fail("\nSucceeded when it should have failed because 0xAA " - "is not in the range of printable characters\n"); - } - - /* check carriage return */ - if(0 != isprint(0x0d)) - { - Fail("\nSucceeded when it should have failed because 0x0d " - "is not in the range of printable characters\n"); - } - - /* check line feed */ - if(0 != isprint(0x0a)) - { - Fail("\nSucceeded when it should have failed because 0x0a " - "is not in the range of printable characters\n"); - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/isspace/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/isspace/test1/test1.cpp deleted file mode 100644 index a5bdf2cb2187c4..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/isspace/test1/test1.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Test #1 for the isspace function -** -** -**==========================================================================*/ - - - -#include - -struct testCase -{ - long result; - char avalue; -}; - - - -PALTEST(c_runtime_isspace_test1_paltest_isspace_test1, "c_runtime/isspace/test1/paltest_isspace_test1") -{ - int i=0; - long result = 0; - - /* - * A structures of the testcases to be tested with - * isspace function - */ - struct testCase testCases[] = - { - {1,'\n'}, - {1,'\t'}, - {1,'\r'}, - {1,'\v'}, - {1,'\f'}, - {1,' '}, - {0,'a'}, - {0,'A'}, - {0,'z'}, - {0,'Z'}, - {0,'r'}, - {0,'R'}, - {0,'0'}, - {0,'*'}, - {0,3} - }; - - /* - * Initialize the PAL - */ - if ( 0 != PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - /* Loop through the testcases */ - for (i=0; i - -PALTEST(c_runtime_iswdigit_test1_paltest_iswdigit_test1, "c_runtime/iswdigit/test1/paltest_iswdigit_test1") -{ - - int result; - int i; - - char16_t passTestCases[] = {'1','2','3','4','5','6','7','8','9'}; - char16_t failTestCases[] = {'a','b','p','$','?',234}; - - if ((PAL_Initialize(argc, argv)) != 0) - { - return (FAIL); - } - - /* Loop through each case. Testing if each is a digit. */ - for(i = 0; i < sizeof(passTestCases) / sizeof(char16_t); i++) - { - result = iswdigit(passTestCases[i]); - - /* The return value is 'non-zero' indicates digit*/ - if (result == 0) - { - Fail("ERROR: iswdigit returned \"%d\" instead indicating" - " \"%c\" is not a digit\n", - result, - passTestCases[i]); - } - } - - /* Loop through each case. Testing if each is a not a digit. */ - for(i = 0; i < sizeof(failTestCases) / sizeof(char16_t); i++) - { - result = iswdigit(failTestCases[i]); - - /* The return value is 'zero' indicates non-digit*/ - if (result != 0) - { - Fail("ERROR: iswdigit returned \"%d\", indicating" - " \"%c\" is a digit\n", - result, - failTestCases[i]); - } - } - PAL_Terminate(); - return (PASS); -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/iswprint/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/iswprint/test1/test1.cpp deleted file mode 100644 index cdc249a62727ca..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/iswprint/test1/test1.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests iswprint with all wide characters, ensuring they are -** consistent with GetStringTypeExW. -** -** -**===================================================================*/ - -#include - -PALTEST(c_runtime_iswprint_test1_paltest_iswprint_test1, "c_runtime/iswprint/test1/paltest_iswprint_test1") -{ - WORD Info; - int ret; - int i; - WCHAR ch; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - for (i=0; i<=0xFFFF; i++) - { - ch = i; - ret = GetStringTypeExW(LOCALE_USER_DEFAULT, CT_CTYPE1, &ch, 1, &Info); - if (!ret) - { - Fail("GetStringTypeExW failed to get information for %#X!\n", ch); - } - - ret = iswprint(ch); - if (Info & (C1_BLANK|C1_PUNCT|C1_ALPHA|C1_DIGIT)) - { - if (!ret) - { - Fail("iswprint returned incorrect results for %#X: " - "expected printable\n", ch); - } - } - else - { - if (ret) - { - Fail("iswprint returned incorrect results for %#X: " - "expected non-printable\n", ch); - } - } - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/iswspace/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/iswspace/test1/test1.cpp deleted file mode 100644 index 4d9de5d01a67e8..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/iswspace/test1/test1.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Tests iswspace with a range of wide characters. -** -** -** -**==========================================================================*/ - - - -#include - -PALTEST(c_runtime_iswspace_test1_paltest_iswspace_test1, "c_runtime/iswspace/test1/paltest_iswspace_test1") -{ - int ret; - int i; - - struct testChars - { - WCHAR charValue; - int result; - }; - - /* create an array of chars that test the range of possible characters */ - struct testChars testChars1[] = - { - {0x00,0}, /* null */ - {0x09,1}, /* open circle */ - {0x0D,1}, /* musical note */ - {0x20,1}, /* space */ - {0x3F,0}, /* ? */ - {0x5E,0}, /* ^ */ - {0x7B,0}, /* { */ - {0x86,0}, /* a with circle on top */ - {0x9F,0}, /* slanted f */ - {0xC4,0}, /* long dash */ - {0xE5,0} /* sigma */ - }; - - if (0 != PAL_Initialize(argc, argv)) - { - return FAIL; - } - - for (i = 0; i < (sizeof(testChars1) / sizeof(struct testChars)); i++) - { - - ret = iswspace(testChars1[i].charValue); - - if((ret==0) && (testChars1[i].result != 0)) - { - Fail("ERROR: wide character %#X IS considered a space, " - "but iswspace did NOT indicate it was one with error %u.\n", - testChars1[i].charValue, - GetLastError()); - } - - if((ret!=0) && (testChars1[i].result == 0)) - { - Fail("ERROR: wide character %#X is NOT considered a space, " - "but iswspace DID indicate it was a space with error %u.\n", - testChars1[i].charValue, - GetLastError()); - } - } - - - PAL_Terminate(); - - return PASS; -} - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/iswupper/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/iswupper/test1/test1.cpp deleted file mode 100644 index 7106aef6cd1b4d..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/iswupper/test1/test1.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests the PAL implementation of the iswupper function -** Check that a number of characters return the correct -** values for whether they are upper case or not. -** -** -**===================================================================*/ - -#define UNICODE -#include - - -struct testCase -{ - int CorrectResult; - WCHAR character; -}; - -PALTEST(c_runtime_iswupper_test1_paltest_iswupper_test1, "c_runtime/iswupper/test1/paltest_iswupper_test1") -{ - - int result; - int i; - - /* Note: 1 iff char = A..Z - 0 iff char =~ A..Z - */ - - struct testCase testCases[] = - { - {1, 'A'}, /* Basic cases */ - {1, 'Z'}, - {0, 'b'}, /* Lower case */ - {0, '?'}, /* Characters without case */ - {0, 230} - }; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - /* Loop through each case. Check to see if each is upper case or - not. - */ - - for(i = 0; i < sizeof(testCases) / sizeof(struct testCase); i++) - { - - result = iswupper(testCases[i].character); - - /* The return value is 'non-zero' for success. This if condition - * will still work if that non-zero isn't just 1 - */ - if ( ((testCases[i].CorrectResult == 1) && (result == 0)) || - ( (testCases[i].CorrectResult == 0) && (result != 0) )) - { - Fail("ERROR: iswupper returned %i instead of %i for " - "character %c.\n", - result, - testCases[i].CorrectResult, - testCases[i].character); - } - - } - - - PAL_Terminate(); - return PASS; -} - - - - - - - - - - - - - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/isxdigit/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/isxdigit/test1/test1.cpp deleted file mode 100644 index 8b49147fd6b137..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/isxdigit/test1/test1.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Run through every possible character. For each time that -** isxdigit returns: -** 1, check through a list of the known hex characters to ensure that it -** is really a hex char. Also, when it returns 0, ensure that the character -** isn't a hex character. -** -**==========================================================================*/ - -#include - - -PALTEST(c_runtime_isxdigit_test1_paltest_isxdigit_test1, "c_runtime/isxdigit/test1/paltest_isxdigit_test1") -{ - int i; - - /* Initialize the PAL */ - if ( 0 != PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - /* Loop through each character and call isxdigit for each character */ - for (i=1; i<256; i++) - { - - if (isxdigit(i) == 0) - { - if( ((i>=48) && (i<=57)) || ((i>=97) && (i<=102)) || - ((i>=65) && (i<=70)) ) - { - Fail("ERROR: isxdigit() returns true for '%c' (%d)\n", i, i); - } - } - else - { - if( ((i<48) && (i>58)) || ((i<97) && (i>102)) || - ((i<65) && (i>70)) ) - { - Fail("ERROR: isxdigit() returns false for '%c' (%d)\n", i, i); - } - } - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/llabs/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/llabs/test1/test1.cpp deleted file mode 100644 index 09bf0670bf479b..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/llabs/test1/test1.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Call llabs on a series of values -- negative, positive, -** zero, and the largest negative value of an int64_t. Ensure that -** they are all changed properly to their absolute value. -** -** -**===================================================================*/ - -#include - -struct testCase -{ - int64_t LongLongValue; - int64_t AbsoluteLongLongValue; -}; - -PALTEST(c_runtime_llabs_test1_paltest_llabs_test1, "c_runtime/llabs/test1/paltest_llabs_test1") -{ - - int64_t result=0; - int i=0; - - struct testCase testCases[] = - { - {1234, 1234}, - {-1234, 1234}, - {0, 0}, - {-9223372036854775807LL, 9223372036854775807LL}, /* Max value to abs */ - {9223372036854775807LL, 9223372036854775807LL} - }; - - if (0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - /* Loop through each case. Call llabs on each int64_t and ensure that - the resulting value is correct. - */ - - for(i = 0; i < sizeof(testCases) / sizeof(struct testCase); i++) - { - /* Absolute value on an int64_t */ - result = llabs(testCases[i].LongLongValue); - - if (testCases[i].AbsoluteLongLongValue != result) - { - Fail("ERROR: llabs took the absolute value of '%d' to be '%d' " - "instead of %d.\n", - testCases[i].LongLongValue, - result, - testCases[i].AbsoluteLongLongValue); - } - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/memchr/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/memchr/test1/test1.cpp deleted file mode 100644 index a7e44dbd911f1a..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/memchr/test1/test1.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests the PAL implementation of the memchr function. -** Create a string buffer, and check for a number of -** characters in it. Test to ensure it returns NULL if -** it can't find the character, and that the size argument -** works properly. -** -** -**===================================================================*/ - -#include - -struct testCase -{ - char *result; - char string[50]; - int character; - int length; -}; - - -PALTEST(c_runtime_memchr_test1_paltest_memchr_test1, "c_runtime/memchr/test1/paltest_memchr_test1") -{ - int i = 0; - char *result = NULL; - - /* - * this structure includes several strings to be tested with - * memchr function and the expected results - */ - - struct testCase testCases[]= - { - {"st","corn cup cat cream coast",'s',23}, - /* single instance of char */ - {"st","corn cup cat cream coast",'s',24}, - /* single inst, inst< exact length */ - {"q","corn cup cat cream coastq",'q',25}, - /* single inst at end, inst=exact length */ - {"q","corn cup cat cream coastq",'q',26}, - /* single inst at end, instlen(string) */ - {"st","corn cup cat cream coast",115,24}, - /* single int inst, instlength */ - }; - - - /* Initialize the PAL */ - if ( 0 != PAL_Initialize(argc, argv)) - { - return FAIL; - } - - /* Loop through the testcases in the structure */ - for (i=0; i< sizeof(testCases)/sizeof(struct testCase); i++) - { - /* Need to type cast function in order to compare the result */ - result = (char *)memchr(testCases[i].string, - testCases[i].character,testCases[i].length); - - if (result==NULL) - { - if (testCases[i].result != NULL) - { - Fail("ERROR: Expected memcmp to return \"%s\" instead of" - " NULL\n", testCases[i].result); - } - } - else - { - if (strcmp(result,testCases[i].result)!=0 ) - - { - Fail("ERROR: Expected memcmp to return \"%s\" instead of" - " \"%s\"\n", testCases[i].result, result); - } - - } - } - - PAL_Terminate(); - - return PASS; -} - - - - - - - - - - - - - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/memcmp/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/memcmp/test1/test1.cpp deleted file mode 100644 index c1a17f30a659bb..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/memcmp/test1/test1.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Check that memcmp find identical buffers to be identical, -** and that it correctly orders different buffers. -** -** -**==========================================================================*/ - -#include - -PALTEST(c_runtime_memcmp_test1_paltest_memcmp_test1, "c_runtime/memcmp/test1/paltest_memcmp_test1") -{ - - char testA[] = "aaaaaaaaaaaaaaaaaaaa"; - char testB[] = "aaaaaaaaaaaaaaaaaaaa"; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - if (!(memcmp(testA, testB, 20) == 0)) - { - Fail("memcmp compared two identical buffers and found them to " - "differ.\n"); - } - testB[3] = 'b'; - - if (!(memcmp(testA, testB, 20) < 0) - || !(memcmp(testB, testA, 20) >0 )) - { - Fail("memcmp compared two buffers with different contents, and" - " did not order them correctly.\n"); - } - - if (memcmp(testA, testB, 0) != 0) - { - Fail("memcmp didn't return 0 when comparing buffers of length 0.\n"); - } - - PAL_Terminate(); - return PASS; -} - - - - - - - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/memmove/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/memmove/test1/test1.cpp deleted file mode 100644 index 476ba01f5f276c..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/memmove/test1/test1.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Test that memmove correctly copies text from one buffer -** to another even when the buffers overlap. -** -** -**==========================================================================*/ - -#include - -PALTEST(c_runtime_memmove_test1_paltest_memmove_test1, "c_runtime/memmove/test1/paltest_memmove_test1") -{ - char testA[11] = "abcdefghij"; - char testB[15] = "aabbccddeeffgg"; - char testC[15] = "aabbccddeeffgg"; - char testD[15] = "aabbccddeeffgg"; - char insString[4] = "zzz"; - char *retVal; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - /* move a string onto itself */ - retVal = (char *)memmove(testA + 2, testA, 8); - if (retVal != testA + 2) - { - Fail("The return value should have been the value of the destination" - "pointer, but wasn't\n"); - } - - /*Check the most likely error*/ - if (memcmp(testA, "ababababab", 11) == 0) - { - Fail("memmove should have saved the characters in the region of" - " overlap between source and destination, but didn't.\n"); - } - - if (memcmp(testA, "ababcdefgh", 11) != 0) - { - /* not sure what exactly went wrong. */ - Fail("memmove was called on a region containing the characters" - " \"abcdefghij\". It was to move the first 8 positions to" - " the last 8 positions, giving the result \"ababcdefgh\". " - " Instead, it gave the result \"%s\".\n", testA); - } - - /* move a string to the front of testB */ - retVal = (char *)memmove(testB, insString, 3); - if(retVal != testB) - { - Fail("memmove: The function did not return the correct " - "string.\n"); - } - - if(memcmp(testB, "zzzbccddeeffgg",15) != 0) - { - Fail("memmove: The function failed to move the string " - "correctly.\n"); - } - - - /* move a string to the middle of testC */ - retVal = (char*)memmove(testC+5, insString, 3); - if(retVal != testC+5) - { - Fail("memmove: The function did not return the correct " - "string.\n"); - } - - if(memcmp(testC, "aabbczzzeeffgg",15) != 0) - { - Fail("memmove: The function failed to move the string " - "correctly.\n"); - } - - - /* move a string to the end of testD */ - retVal = (char*)memmove(testD+11, insString, 3); - if(retVal != testD+11) - { - Fail("memmove: The function did not return the correct " - "string.\n"); - } - - if(memcmp(testD, "aabbccddeefzzz",15) != 0) - { - Fail("memmove: The function failed to move the string " - "correctly.\n"); - } - - PAL_Terminate(); - return PASS; - -} - - - - - - - - - - - - - - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/memset/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/memset/test1/test1.cpp deleted file mode 100644 index ee8d92fd4ab538..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/memset/test1/test1.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Check that memset correctly fills a destination buffer -** without overflowing it. -** -** -**==========================================================================*/ - -#include - -PALTEST(c_runtime_memset_test1_paltest_memset_test1, "c_runtime/memset/test1/paltest_memset_test1") -{ - - char testA[22] = "bbbbbbbbbbbbbbbbbbbbb"; - char *retVal; - - int i; - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - retVal = (char *)memset(testA, 'a', 20); - if (retVal != testA) - { - Fail("memset should have returned the value of the destination" - "pointer, but didn't"); - } - - for(i = 0; i<20; i++) - { - if (testA[i]!= 'a') - { - Fail("memset didn't set the destination bytes.\n"); - } - } - if (testA[20] == 'a') - { - Fail("memset overfilled the destination buffer.\n"); - } - - PAL_Terminate(); - return PASS; -} - - - - - - - - - - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/strcat/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/strcat/test1/test1.cpp deleted file mode 100644 index 7c8ec61fe9f6e9..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/strcat/test1/test1.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: -** Concatenate three strings into one string. Each time, check to ensure -** the pointer returned was what we expected. When finished, compare the -** newly formed string to what it should be to ensure no characters were -** lost. -** -** -**==========================================================================*/ - -#include - - -PALTEST(c_runtime_strcat_test1_paltest_strcat_test1, "c_runtime/strcat/test1/paltest_strcat_test1") -{ - char dest[80]; - char *test = "foo bar baz"; - char *str1 = "foo "; - char *str2 = "bar "; - char *str3 = "baz"; - char *ptr; - - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - dest[0] = 0; - - ptr = strcat(dest, str1); - if (ptr != dest) - { - Fail("ERROR: Expected strcat to return ptr to %p, got %p", dest, ptr); - } - - ptr = strcat(dest, str2); - if (ptr != dest) - { - Fail("ERROR: Expected strcat to return ptr to %p, got %p", dest, ptr); - } - - ptr = strcat(dest, str3); - if (ptr != dest) - { - Fail("ERROR: Expected strcat to return ptr to %p, got %p", dest, ptr); - } - - if (strcmp(dest, test) != 0) - { - Fail("ERROR: Expected strcat to give \"%s\", got \"%s\"\n", - test, dest); - } - - PAL_Terminate(); - - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/strchr/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/strchr/test1/test1.cpp deleted file mode 100644 index 0c706b8b538e95..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/strchr/test1/test1.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: -** Test this on a character which is in a string, and ensure the pointer -** points to that character. Then check the string for the null character, -** which the return pointer should point to. Then search for a character not -** in the string and check that the return value is NULL. -** -** -**==========================================================================*/ - -#include - -struct testCase -{ - int result; - char string[50]; - int character; -}; - - - -PALTEST(c_runtime_strchr_test1_paltest_strchr_test1, "c_runtime/strchr/test1/paltest_strchr_test1") -{ - int i = 0; - char *result; - - /* - * this structure includes several strings to be tested with - * strchr function and the expected results - */ - - struct testCase testCases[]= - { - {22,"corn cup cat cream coast",'s'}, - {10,"corn cup cat cream coast",'a'}, - {2,"This is a test",'i'}, - {10,"This is a test",'t'}, - {'\0',"This is a test",'b'},/* zero used instead of NULL */ - {'\0',"This is a test",121},/* zero used instead of NULL */ - {4,"This is a test of the function",' '}, - {25,"This is a test of the function",'c'}, - {'\0',"This is a test of the function",'C'}, - {24,"corn cup cat cream coast", '\0'}/* zero used instead of NULL */ - }; - - if (0 != PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - /* Loop through the structure and test each case */ - - for (i=0; i< sizeof(testCases)/sizeof(struct testCase); i++) - { - result = strchr(testCases[i].string,testCases[i].character); - if (result==NULL) - { - if (testCases[i].result != 0) - { - Fail("Expected strchr() to return \"%s\" instead of NULL!\n", - testCases[i].string + testCases[i].result); - } - } - else - { - if (result != testCases[i].string + testCases[i].result) - { - Fail("Expected strchr() to return \"%s\" instead of \"%s\"!\n", - testCases[i].string + testCases[i].result, result); - } - } - - } - - PAL_Terminate(); - - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/strcmp/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/strcmp/test1/test1.cpp deleted file mode 100644 index dadbeb5cb5b334..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/strcmp/test1/test1.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: -** Compare a number of different strings against each other, ensure that the -** three return values are given at the appropriate times. -** -** -**==========================================================================*/ - -#include - -typedef struct -{ - int result; - char string1[50]; - char string2[50]; -} testCase; - -PALTEST(c_runtime_strcmp_test1_paltest_strcmp_test1, "c_runtime/strcmp/test1/paltest_strcmp_test1") -{ - testCase testCases[]= - { - {0,"Hello","Hello"}, - {1,"hello","Hello"}, - {-1,"Hello","hello"}, - {0,"0Test","0Test"}, - {0,"***???","***???"}, - {0,"Testing the string for string comparison","Testing the string for " - "string comparison"}, - {-1,"Testing the string for string comparison","Testing the string for " - "string comparsioa"}, - {1,"Testing the string for string comparison","Testing the string for " - "comparison"}, - {-1,"aaaabbbbb","aabcdefeccg"} - }; - - int i = 0; - int result = 0; - - /* - * Initialize the PAL - */ - if (0 != PAL_Initialize(argc, argv)) - { - return FAIL; - } - - /* Loop through structure and test each case */ - for (i=0; i < sizeof(testCases)/sizeof(testCase); i++) - { - result = strcmp(testCases[i].string1,testCases[i].string2); - - /* Compare returned value */ - if( ((result == 0) && (testCases[i].result !=0)) || - ((result <0) && (testCases[i].result !=-1)) || - ((result >0) && (testCases[i].result !=1)) ) - { - Fail("ERROR: strcmp returned %d instead of %d\n", - result, testCases[i].result); - } - - } - - PAL_Terminate(); - - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/strcpy/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/strcpy/test1/test1.cpp deleted file mode 100644 index acb1e68b013e99..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/strcpy/test1/test1.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: -** Call the function to copy into an empty buffer. Check that the return value -** is pointing at the destination buffer. Also compare the string copied to -** the original string, to ensure they are the same. -** -** -**==========================================================================*/ - -#include - - -PALTEST(c_runtime_strcpy_test1_paltest_strcpy_test1, "c_runtime/strcpy/test1/paltest_strcpy_test1") -{ - char dest[80]; - char *result = "foo"; - char str[] = {'f','o','o',0,'b','a','r',0}; - char *ret; - - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - ret = strcpy(dest, str); - - if (ret != dest) - { - Fail("Expected strcpy to return %p, got %p!\n", dest, ret); - - } - - if (strcmp(dest, result) != 0) - { - Fail("Expected strcpy to give \"%s\", got \"%s\"!\n", result, dest); - } - - - PAL_Terminate(); - - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/strlen/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/strlen/test1/test1.cpp deleted file mode 100644 index b19b3fec34457f..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/strlen/test1/test1.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: -** Check the length of a string and the length of a 0 character string to -** see that this function returns the correct values for each. -** -** -**==========================================================================*/ - -#include - -PALTEST(c_runtime_strlen_test1_paltest_strlen_test1, "c_runtime/strlen/test1/paltest_strlen_test1") -{ - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - if (strlen("foo") != 3) - Fail("ERROR: strlen(\"foo\") != 3\n"); - - if (strlen("") != 0) - Fail("ERROR: strlen(\"\") != 0\n"); - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/strncat/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/strncat/test1/test1.cpp deleted file mode 100644 index 240a78f9fef276..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/strncat/test1/test1.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: -** Concatenate a few strings together, setting different lengths to be -** used for each one. Check to ensure the pointers which are returned are -** correct, and that the final string is what was expected. -** -** -**==========================================================================*/ - -#include - - -PALTEST(c_runtime_strncat_test1_paltest_strncat_test1, "c_runtime/strncat/test1/paltest_strncat_test1") -{ - char dest[80]; - char *test = "foo barbaz"; - char *str1 = "foo "; - char *str2 = "bar "; - char *str3 = "baz"; - char *ptr; - int i; - - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - dest[0] = 0; - for (i=1; i<80; i++) - { - dest[i] = 'x'; - } - - ptr = strncat(dest, str1, strlen(str1)); - if (ptr != dest) - { - Fail("ERROR: Expected strncat to return ptr to %p, got %p", dest, ptr); - } - - ptr = strncat(dest, str2, 3); - if (ptr != dest) - { - Fail("ERROR: Expected strncat to return ptr to %p, got %p", dest, ptr); - } - if (dest[7] != 0) - { - Fail("ERROR: strncat did not place a terminating NULL!"); - } - - ptr = strncat(dest, str3, 20); - if (ptr != dest) - { - Fail("ERROR: Expected strncat to return ptr to %p, got %p", dest, ptr); - } - if (strcmp(dest, test) != 0) - { - Fail("ERROR: Expected strncat to give \"%s\", got \"%s\"\n", - test, dest); - } - if (dest[strlen(test)+1] != 'x') - { - Fail("strncat went out of bounds!\n"); - } - - PAL_Terminate(); - - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/strncmp/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/strncmp/test1/test1.cpp deleted file mode 100644 index c39498739f1df6..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/strncmp/test1/test1.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: -** Test to ensure all three possible return values are given under the -** appropriate circumstance. Also, uses different sizes, to only compare -** portions of strings, checking to make sure these return the correct value. -** -** -**==========================================================================*/ - -#include - -typedef struct -{ - int result; - char string1[50]; - char string2[50]; - int number; -} testCase; - -PALTEST(c_runtime_strncmp_test1_paltest_strncmp_test1, "c_runtime/strncmp/test1/paltest_strncmp_test1") -{ - testCase testCases[]= - { - {0,"Hello","Hello",5}, - {1,"hello","Hello",3}, - {-1,"Hello","hello",5}, - {0,"heLLo","heLLo",5}, - {1,"hello","heLlo",5}, - {-1,"heLlo","hello",5}, - {0,"0Test","0Test",5}, - {0,"***???","***???",6}, - {0,"Testing the string for string comparison","Testing the string for " - "string comparison",40}, - {-1,"Testing the string for string comparison","Testing the string for " - "string comparsioa",40}, - {1,"Testing the string for string comparison","Testing the string for " - "comparison",34}, - {0,"aaaabbbbb","aabcdefeccg",2}, - {0,"abcd","abcd",10} - }; - - int i=0; - int iresult=0; - - /* - * Initialize the PAL - */ - if (0 != PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - for (i=0; i< sizeof(testCases)/sizeof(testCase); i++) - { - iresult = strncmp(testCases[i].string1,testCases[i].string2, - testCases[i].number); - - if( ((iresult == 0) && (testCases[i].result !=0)) || - ((iresult <0) && (testCases[i].result !=-1)) || - ((iresult >0) && (testCases[i].result !=1)) ) - - { - Fail("ERROR: strncmp returned %d instead of %d\n", - iresult, testCases[i].result); - } - - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/strncpy/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/strncpy/test1/test1.cpp deleted file mode 100644 index b934d3cfb65546..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/strncpy/test1/test1.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: -** Test to see that you can copy a portion of a string into a new buffer. -** Also check that the strncpy function doesn't overflow when it is used. -** Finally check that if the number of characters given is greater than the -** amount to copy, that the destination buffer is padded with NULLs. -** -** -**==========================================================================*/ - -#include - - -PALTEST(c_runtime_strncpy_test1_paltest_strncpy_test1, "c_runtime/strncpy/test1/paltest_strncpy_test1") -{ - char dest[80]; - char *result = "foobar"; - char *str = "foobar\0baz"; - char *ret; - int i; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - for (i=0; i<80; i++) - { - dest[i] = 'x'; - } - - ret = strncpy(dest, str, 3); - if (ret != dest) - { - Fail("Expected strncpy to return %p, got %p!\n", dest, ret); - } - - if (strncmp(dest, result, 3) != 0) - { - Fail("Expected strncpy to give \"%s\", got \"%s\"!\n", result, dest); - } - - if (dest[3] != 'x') - { - Fail("strncpy overflowed!\n"); - } - - ret = strncpy(dest, str, 40); - if (ret != dest) - { - Fail("Expected strncpy to return %p, got %p!\n", dest, ret); - } - - if (strcmp(dest, result) != 0) - { - Fail("Expected strncpy to give \"%s\", got \"%s\"!\n", result, dest); - } - - for (i=strlen(str); i<40; i++) - { - if (dest[i] != 0) - { - Fail("strncpy failed to pad the destination with NULLs!\n"); - } - } - - if (dest[40] != 'x') - { - Fail("strncpy overflowed!\n"); - } - - - - PAL_Terminate(); - - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/strpbrk/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/strpbrk/test1/test1.cpp deleted file mode 100644 index b2b90edea7e934..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/strpbrk/test1/test1.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: -** Search a string for characters in a given character set and ensure the -** pointer returned points to the first occurrence. Check to see that the -** function returns NULL if the character is not found. -** -** -**==========================================================================*/ - -#include - -struct testCase -{ - char *result; - char *string1; - char *string2; -}; - -PALTEST(c_runtime_strpbrk_test1_paltest_strpbrk_test1, "c_runtime/strpbrk/test1/paltest_strpbrk_test1") -{ - char *ptr = NULL; - int i = 0; - - /* - * this structure includes several strings to be tested with - * strpbk function and the expected results - */ - - struct testCase testCases[] = - { - {"t cream coast","corn cup cat cream coast","sit"}, - {"eam coast","corn cup cat cream coast","like"}, - {"is is a test","This is a test","circle"}, - {"a test","This is a test","way"}, - {NULL,"This is a test","boo"}, - {NULL,"This is a test","123"}, - {" is a test of the function","This is a test of the function", - "zzz xx"} - }; - - - if (0 != PAL_Initialize(argc, argv)) - { - return FAIL; - } - - /* A loop to go through the testcases in the structure */ - - for (i=0; i< sizeof(testCases)/sizeof(struct testCase); i++) - { - ptr = strpbrk(testCases[i].string1,testCases[i].string2); - if (ptr==NULL) - { - if (testCases[i].result != NULL) - { - Fail("Expected strpbrk() to return %s, got NULL!\n", - testCases[i].result); - } - } - else - { - if (strcmp(ptr,testCases[i].result)!=0 ) - - { - Fail("Expected strpbrk() to return %s, got %s!\n", - testCases[i].result,ptr); - } - - } - - } - - - PAL_Terminate(); - - return PASS; -} - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/strrchr/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/strrchr/test1/test1.cpp deleted file mode 100644 index 85e53eb2a8631a..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/strrchr/test1/test1.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: \ -** Search a string for a given character. Search for a character contained -** in the string, and ensure the pointer returned points to it. Then search -** for the null character, and ensure the pointer points to that. Finally -** search for a character which is not in the string and ensure that it -** returns NULL. -** -** -**==========================================================================*/ - -#include - - -PALTEST(c_runtime_strrchr_test1_paltest_strrchr_test1, "c_runtime/strrchr/test1/paltest_strrchr_test1") -{ - char *str = "foo bar baz"; - char *ptr; - - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - ptr = strrchr(str, 'b'); - if (ptr != str + 8) - { - Fail("Expected strrchr() to return %p, got %p!\n", str + 8, ptr); - } - - ptr = strrchr(str, 0); - if (ptr != str + 11) - { - Fail("Expected strrchr() to return %p, got %p!\n", str + 11, ptr); - } - - ptr = strrchr(str, 'x'); - if (ptr != NULL) - { - Fail("Expected strrchr() to return NULL, got %p!\n", ptr); - } - - PAL_Terminate(); - - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/strstr/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/strstr/test1/test1.cpp deleted file mode 100644 index e50d5bda12b819..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/strstr/test1/test1.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: -** Check three cases of searching for a string within a string. First when -** the string is contained, check that the pointer returned points to it. -** Then when it isn't contained, ensure it returns null. And when the string -** we're searching for is empty, it should return a pointer to the string -** we're searching through.Test #1 for the strstr function -** -** -**==========================================================================*/ - - - -#include - - -struct testCase -{ - char *result; - char *string1; - char *string2; - -}; - -PALTEST(c_runtime_strstr_test1_paltest_strstr_test1, "c_runtime/strstr/test1/paltest_strstr_test1") -{ - int i=0; - char *ptr=NULL; - - struct testCase testCases[]= - { - {"is is a test", "This is a test","is"}, - {"fghijkl","abcdefghijkl","fgh"}, - {NULL,"aabbccddeeffgg","h"}, - {NULL,"aabb", "eeeeeee"}, - {"AAA", "BBddfdaaaaAAA","A"}, - {"fdaaaaAAA", "BBddfdaaaaAAA","f"}, - {"aadfsadfas","aadfsadfas",""}, - {NULL,"","ccc"} - }; - - /* - * Initialize the PAL - */ - if (0 != PAL_Initialize(argc, argv)) - { - return FAIL; - } - - for (i=0; i - -struct testCase -{ - int lower; - int start; -}; - -PALTEST(c_runtime_tolower_test1_paltest_tolower_test1, "c_runtime/tolower/test1/paltest_tolower_test1") -{ - - int result; - int i; - - struct testCase testCases[] = - { - {'a', 'A'}, /* Basic cases */ - {'z', 'Z'}, - {'b', 'b'}, /* Lower case */ - {'?', '?'}, /* Characters without case */ - {230, 230} - }; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - /* Loop through each case. Convert each character to lower case - and then compare to ensure that it is the correct value. - */ - - for(i = 0; i < sizeof(testCases) / sizeof(struct testCase); i++) - { - /*Convert to lower case*/ - result = tolower(testCases[i].start); - - if (testCases[i].lower != result) - { - Fail("ERROR: tolower lowered \"%i\" to %i instead of %i.\n", - testCases[i].start, result, testCases[i].lower); - } - - } - - - PAL_Terminate(); - return PASS; -} - - - - - - - - - - - - - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/toupper/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/toupper/test1/test1.cpp deleted file mode 100644 index 1683aa3b9fc6d1..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/toupper/test1/test1.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c (toupper) -** -** -** Purpose: Tests the PAL implementation of the toupper function. -** Check that the toupper function makes lower case -** character a capital. Also check that it has no effect -** on upper case letters and special characters. -** -** -**===================================================================*/ - -#include - -struct testCase -{ - int upper; - int start; -}; - -PALTEST(c_runtime_toupper_test1_paltest_toupper_test1, "c_runtime/toupper/test1/paltest_toupper_test1") -{ - - int result; - int i; - - struct testCase testCases[] = - { - {'A', 'a'}, /* Basic cases */ - {'Z', 'z'}, - {'B', 'B'}, /* Upper case */ - {'%', '%'}, /* Characters without case */ - {157, 157} - }; - - if ((PAL_Initialize(argc, argv)) != 0) - { - return FAIL; - } - - - /* Loop through each case. Convert each character to upper case - and then compare to ensure that it is the correct value. - */ - for(i = 0; i < sizeof(testCases) / sizeof(struct testCase); i++) - { - /*Convert to upper case*/ - result = toupper(testCases[i].start); - - if (testCases[i].upper != result) - { - Fail("ERROR: toupper capitalized \"%c\" to %c instead of %c.\n", - testCases[i].start, result, testCases[i].upper); - } - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/towlower/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/towlower/test1/test1.cpp deleted file mode 100644 index e17aad88bc46d8..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/towlower/test1/test1.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c -** -** Purpose: Tests the PAL implementation of the towlower function. -** Check that the tolower function makes capital character -** lower case. Also check that it has no effect on lower -** case letters and special characters. -** -** -**===================================================================*/ - -#include - -struct testCase -{ - WCHAR lower; - WCHAR start; -}; - -PALTEST(c_runtime_towlower_test1_paltest_towlower_test1, "c_runtime/towlower/test1/paltest_towlower_test1") -{ - - int result; - int i; - - struct testCase testCases[] = - { - {'a', 'A'}, /* Basic cases */ - {'z', 'Z'}, - {'b', 'b'}, /* Lower case */ - {'?', '?'}, /* Characters without case */ - {230, 230} - }; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - - /* Loop through each case. Convert each character to lower case - and then compare to ensure that it is the correct value. - */ - - for(i = 0; i < sizeof(testCases) / sizeof(struct testCase); i++) - { - /*Convert to lower case*/ - result = towlower(testCases[i].start); - - if (testCases[i].lower != result) - { - Fail("ERROR: towlower lowered \"%c\" to %c instead of %c.\n", - testCases[i].start, result, testCases[i].lower); - } - - } - - - PAL_Terminate(); - return PASS; -} - - - - - - - - - - - - - diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/towupper/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/towupper/test1/test1.cpp deleted file mode 100644 index d2fd880d17148a..00000000000000 --- a/src/coreclr/pal/tests/palsuite/c_runtime/towupper/test1/test1.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*===================================================================== -** -** Source: test1.c(towupper) -** -** -** Purpose: Tests the PAL implementation of the towupper function. -** Check that the towupper function makes lower case -** character a capital. Also check that it has no effect -** on upper case letters and special characters. -** -** -**===================================================================*/ - -#include - -struct testCase -{ - WCHAR upper; - WCHAR start; -}; - -PALTEST(c_runtime_towupper_test1_paltest_towupper_test1, "c_runtime/towupper/test1/paltest_towupper_test1") -{ - - int result; - int i; - - struct testCase testCases[] = - { - {'A', 'a'}, /* Basic cases */ - {'Z', 'z'}, - {'B', 'B'}, /* Upper case */ - {'%', '%'}, /* Characters without case */ - {157, 157} - }; - - if ((PAL_Initialize(argc, argv)) != 0) - { - return FAIL; - } - - - /* Loop through each case. Convert each character to upper case - and then compare to ensure that it is the correct value. - */ - - for(i = 0; i < sizeof(testCases) / sizeof(struct testCase); i++) - { - /*Convert to upper case*/ - result = towupper(testCases[i].start); - - if (testCases[i].upper != result) - { - Fail("ERROR: towupper capitalized \"%c\" to %c instead of %c.\n", - testCases[i].start, result, testCases[i].upper); - } - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/compilableTests.txt b/src/coreclr/pal/tests/palsuite/compilableTests.txt index eba5bf5faac18d..b358bd693f36f3 100644 --- a/src/coreclr/pal/tests/palsuite/compilableTests.txt +++ b/src/coreclr/pal/tests/palsuite/compilableTests.txt @@ -1,20 +1,3 @@ -c_runtime/atof/test1/paltest_atof_test1 -c_runtime/atoi/test1/paltest_atoi_test1 -c_runtime/isalnum/test1/paltest_isalnum_test1 -c_runtime/isalpha/test1/paltest_isalpha_test1 -c_runtime/isdigit/test1/paltest_isdigit_test1 -c_runtime/isprint/test1/paltest_isprint_test1 -c_runtime/isprint/test2/paltest_isprint_test2 -c_runtime/isspace/test1/paltest_isspace_test1 -c_runtime/iswdigit/test1/paltest_iswdigit_test1 -c_runtime/iswspace/test1/paltest_iswspace_test1 -c_runtime/iswupper/test1/paltest_iswupper_test1 -c_runtime/isxdigit/test1/paltest_isxdigit_test1 -c_runtime/llabs/test1/paltest_llabs_test1 -c_runtime/memchr/test1/paltest_memchr_test1 -c_runtime/memcmp/test1/paltest_memcmp_test1 -c_runtime/memmove/test1/paltest_memmove_test1 -c_runtime/memset/test1/paltest_memset_test1 c_runtime/sscanf_s/test1/paltest_sscanf_test1 c_runtime/sscanf_s/test10/paltest_sscanf_test10 c_runtime/sscanf_s/test11/paltest_sscanf_test11 @@ -32,21 +15,6 @@ c_runtime/sscanf_s/test6/paltest_sscanf_test6 c_runtime/sscanf_s/test7/paltest_sscanf_test7 c_runtime/sscanf_s/test8/paltest_sscanf_test8 c_runtime/sscanf_s/test9/paltest_sscanf_test9 -c_runtime/strcat/test1/paltest_strcat_test1 -c_runtime/strchr/test1/paltest_strchr_test1 -c_runtime/strcmp/test1/paltest_strcmp_test1 -c_runtime/strcpy/test1/paltest_strcpy_test1 -c_runtime/strlen/test1/paltest_strlen_test1 -c_runtime/strncat/test1/paltest_strncat_test1 -c_runtime/strncmp/test1/paltest_strncmp_test1 -c_runtime/strncpy/test1/paltest_strncpy_test1 -c_runtime/strpbrk/test1/paltest_strpbrk_test1 -c_runtime/strrchr/test1/paltest_strrchr_test1 -c_runtime/strstr/test1/paltest_strstr_test1 -c_runtime/tolower/test1/paltest_tolower_test1 -c_runtime/toupper/test1/paltest_toupper_test1 -c_runtime/towlower/test1/paltest_towlower_test1 -c_runtime/towupper/test1/paltest_towupper_test1 c_runtime/wcscat/test1/paltest_wcscat_test1 c_runtime/wcschr/test1/paltest_wcschr_test1 c_runtime/wcscmp/test1/paltest_wcscmp_test1 @@ -64,9 +32,6 @@ c_runtime/wcstoul/test3/paltest_wcstoul_test3 c_runtime/wcstoul/test4/paltest_wcstoul_test4 c_runtime/wcstoul/test5/paltest_wcstoul_test5 c_runtime/wcstoul/test6/paltest_wcstoul_test6 -c_runtime/_alloca/test1/paltest_alloca_test1 -c_runtime/_rotl/test1/paltest_rotl_test1 -c_runtime/_rotr/test1/paltest_rotr_test1 c_runtime/_vsnprintf_s/test1/paltest_vsnprintf_test1 c_runtime/_vsnprintf_s/test10/paltest_vsnprintf_test10 c_runtime/_vsnprintf_s/test11/paltest_vsnprintf_test11 @@ -101,11 +66,6 @@ filemapping_memmgt/GetProcAddress/test1/paltest_getprocaddress_test1 filemapping_memmgt/GetProcAddress/test2/paltest_getprocaddress_test2 filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/paltest_probememory_probememory_neg1 filemapping_memmgt/ProbeMemory/test1/paltest_probememory_test1 -loader/LoadLibraryA/test1/paltest_loadlibrarya_test1 -loader/LoadLibraryA/test2/paltest_loadlibrarya_test2 -loader/LoadLibraryA/test3/paltest_loadlibrarya_test3 -loader/LoadLibraryA/test5/paltest_loadlibrarya_test5 -loader/LoadLibraryA/test7/paltest_loadlibrarya_test7 loader/LoadLibraryW/test1/paltest_loadlibraryw_test1 loader/LoadLibraryW/test2/paltest_loadlibraryw_test2 loader/LoadLibraryW/test3/paltest_loadlibraryw_test3 @@ -163,8 +123,6 @@ miscellaneous/SetEnvironmentVariableW/test4/paltest_setenvironmentvariablew_test miscellaneous/SetLastError/test1/paltest_setlasterror_test1 pal_specific/PAL_Initialize_Terminate/test1/paltest_pal_initialize_terminate_test1 pal_specific/PAL_Initialize_Terminate/test2/paltest_pal_initialize_terminate_test2 -pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/paltest_pal_registerlibraryw_unregisterlibraryw_test1 -pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/paltest_reg_unreg_libraryw_neg samples/test1/paltest_samples_test1 samples/test2/paltest_samples_test2 threading/CreateThread/test1/paltest_createthread_test1 @@ -185,8 +143,6 @@ threading/GetCurrentThreadId/test1/paltest_getcurrentthreadid_test1 threading/QueryThreadCycleTime/test1/paltest_querythreadcycletime_test1 threading/ResumeThread/test1/paltest_resumethread_test1 threading/RuntimeEvent/test1/paltest_runtimeevent_test1 -threading/Sleep/test1/paltest_sleep_test1 -threading/Sleep/test2/paltest_sleep_test2 threading/SwitchToThread/test1/paltest_switchtothread_test1 threading/TerminateProcess/test1/paltest_terminateprocess_test1 threading/ThreadPriority/test1/paltest_threadpriority_test1 diff --git a/src/coreclr/pal/tests/palsuite/compileDisabledTests.txt b/src/coreclr/pal/tests/palsuite/compileDisabledTests.txt index 6f826fc83fa0c8..3d73dd7a245092 100644 --- a/src/coreclr/pal/tests/palsuite/compileDisabledTests.txt +++ b/src/coreclr/pal/tests/palsuite/compileDisabledTests.txt @@ -4,7 +4,6 @@ composite/synchronization/criticalsection/paltest_synchronization_criticalsectio composite/synchronization/nativecriticalsection/paltest_synchronization_nativecriticalsection composite/synchronization/nativecs_interlocked/paltest_synchronization_nativecs_interlocked composite/wfmo/paltest_composite_wfmo -c_runtime/iswprint/test1/paltest_iswprint_test1 c_runtime/vprintf/test1/paltest_vprintf_test1 debug_api/DebugBreak/test1/paltest_debugbreak_test1 exception_handling/pal_except/test1/paltest_pal_except_test1 @@ -27,17 +26,6 @@ exception_handling/PAL_TRY_EXCEPT_EX/test1/paltest_pal_try_except_ex_test1 exception_handling/PAL_TRY_EXCEPT_EX/test2/paltest_pal_try_except_ex_test2 exception_handling/PAL_TRY_EXCEPT_EX/test3/paltest_pal_try_except_ex_test3 exception_handling/PAL_TRY_LEAVE_FINALLY/test1/paltest_pal_try_leave_finally_test1 -loader/LoadLibraryA/test6/paltest_loadlibrarya_test6 -loader/LoadLibraryA/test8/paltest_loadlibrarya_test8 -locale_info/CompareStringA/test1/paltest_comparestringa_test1 -locale_info/CompareStringW/test1/paltest_comparestringw_test1 -locale_info/GetLocaleInfoW/test1/paltest_getlocaleinfow_test1 -locale_info/GetLocaleInfoW/test2/paltest_getlocaleinfow_test2 -miscellaneous/IsBadCodePtr/test1/paltest_isbadcodeptr_test1 -miscellaneous/IsBadReadPtr/test1/paltest_isbadreadptr_test1 -miscellaneous/IsBadWritePtr/test1/paltest_isbadwriteptr_test1 -miscellaneous/IsBadWritePtr/test2/paltest_isbadwriteptr_test2 -miscellaneous/IsBadWritePtr/test3/paltest_isbadwriteptr_test3 pal_specific/PAL_get_stderr/test1/paltest_pal_get_stderr_test1 pal_specific/PAL_get_stdin/test1/paltest_pal_get_stdin_test1 pal_specific/PAL_get_stdout/test1/paltest_pal_get_stdout_test1 diff --git a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test1/LoadLibraryA.cpp b/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test1/LoadLibraryA.cpp deleted file mode 100644 index 53c564fad8bbc8..00000000000000 --- a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test1/LoadLibraryA.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================= -** -** Source: loadlibrarya.c -** -** Purpose: Positive test the LoadLibrary API. -** Call LoadLibrary to map a module into the calling -** process address space(DLL file) -** -** -**============================================================*/ -#include - -/* SHLEXT is defined only for Unix variants */ - -#if defined(SHLEXT) -#define ModuleName "librotor_pal"SHLEXT -#else -#define ModuleName "rotor_pal.dll" -#endif - -PALTEST(loader_LoadLibraryA_test1_paltest_loadlibrarya_test1, "loader/LoadLibraryA/test1/paltest_loadlibrarya_test1") -{ - HMODULE ModuleHandle; - int err; - - /* Initialize the PAL environment */ - err = PAL_Initialize(argc, argv); - if(0 != err) - { - ExitProcess(FAIL); - } - - /* load a module */ - ModuleHandle = LoadLibraryExA(ModuleName, NULL, 0); - if(!ModuleHandle) - { - Fail("Failed to call LoadLibrary API!\n"); - } - - /* decrement the reference count of the loaded dll */ - err = FreeLibrary(ModuleHandle); - if(0 == err) - { - Fail("\nFailed to all FreeLibrary API!\n"); - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test2/LoadLibraryA.cpp b/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test2/LoadLibraryA.cpp deleted file mode 100644 index ca8e52c408cc13..00000000000000 --- a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test2/LoadLibraryA.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================= -** -** Source: loadlibrarya.c -** -** Purpose: Negative test the LoadLibraryA API. -** Call LoadLibraryA with a not exist module Name -** -** -**============================================================*/ -#include - -PALTEST(loader_LoadLibraryA_test2_paltest_loadlibrarya_test2, "loader/LoadLibraryA/test2/paltest_loadlibrarya_test2") -{ - HMODULE ModuleHandle; - int err; - const char *pModuleName = "Not-exist-module-name"; - - /* Initialize the PAL environment */ - err = PAL_Initialize(argc, argv); - if(0 != err) - { - return FAIL; - } - - /*try to load a not exist module */ - ModuleHandle = LoadLibraryExA(pModuleName, NULL, 0); - if(NULL != ModuleHandle) - { - Trace("Failed to call LoadLibraryExA with a not exist mudule name, " - "a NULL module handle is expected, but no NULL module handle " - "is returned, error code=%u\n", GetLastError()); - - /* decrement the reference count of the loaded module */ - err = FreeLibrary(ModuleHandle); - if(0 == err) - { - Trace("\nFailed to all FreeLibrary API to decrement " - "the reference count of the loaded module, " - "error code = %u\n", GetLastError()); - - } - - Fail(""); - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test3/loadlibrarya.cpp b/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test3/loadlibrarya.cpp deleted file mode 100644 index cbb41f3457baef..00000000000000 --- a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test3/loadlibrarya.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================= -** -** Source: loadlibrarya.c -** -** Purpose: Negative test the LoadLibrary API with NULL module -** name. -** -** -**============================================================*/ -#include - -PALTEST(loader_LoadLibraryA_test3_paltest_loadlibrarya_test3, "loader/LoadLibraryA/test3/paltest_loadlibrarya_test3") -{ - HMODULE ModuleHandle; - int err; - - /*Initialize the PAL environment*/ - err = PAL_Initialize(argc, argv); - if(0 != err) - { - return FAIL; - } - - /*load a module by passing a NULL module name*/ - ModuleHandle = LoadLibraryExA(NULL, NULL, 0); - if(NULL != ModuleHandle) - { - Fail("\nFailed to call LoadLibraryExA API for a negative test, " - "call LoadLibraryExA with NULL moudle name, a NULL module " - "handle is expected, but no NULL module handle is returned, " - "error code =%u\n", GetLastError()); - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test5/loadlibrarya.cpp b/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test5/loadlibrarya.cpp deleted file mode 100644 index b8f609001f2424..00000000000000 --- a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test5/loadlibrarya.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================= -** -** Source: loadlibrarya.c -** -** Purpose: Negative test the LoadLibraryA API. -** Call LoadLibraryA by passing a module name -** without extension but with a trailing dot. -** -** -**============================================================*/ -#include - -PALTEST(loader_LoadLibraryA_test5_paltest_loadlibrarya_test5, "loader/LoadLibraryA/test5/paltest_loadlibrarya_test5") -{ - HMODULE ModuleHandle; - char ModuleName[_MAX_FNAME]; - int err; - - /* Initialize the PAL environment */ - err = PAL_Initialize(argc, argv); - if(0 != err) - { - return FAIL; - } - - memset(ModuleName, 0, _MAX_FNAME); - - /*Module name without extension but with a trailing dot*/ -#if WIN32 - sprintf_s(ModuleName, ARRAY_SIZE(ModuleName), "%s", "rotor_pal."); -#else - /* Under FreeBSD */ - sprintf_s(ModuleName, ARRAY_SIZE(ModuleName), "%s", "librotor_pal."); -#endif - - /* load a module which does not have the file extension, - * but has a trailing dot - */ - ModuleHandle = LoadLibraryExA(ModuleName, NULL, 0); - if(NULL != ModuleHandle) - { - Trace("Failed to call LoadLibraryExA API for a negative test " - "call LoadLibraryExA with module name which does not have " - "extension except a trailing dot, a NULL module handle is" - "expected, but no NULL module handle is returned, " - "error code = %u\n", GetLastError()); - - - /* decrement the reference count of the loaded dll */ - err = FreeLibrary(ModuleHandle); - if(0 == err) - { - Trace("\nFailed to call FreeLibrary API, " - "error code = %u\n", GetLastError()); - } - - Fail(""); - } - - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.cpp b/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.cpp deleted file mode 100644 index 6e2cdeb7c9a715..00000000000000 --- a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: dllmain.c -** -** Purpose: Test to ensure DllMain() is called with DLL_THREAD_DETACH -** only the initial time that the library is loaded. -** -** Depends: None -** - -** -**===========================================================================*/ - -#include - -/* count of the number of times DllMain() - * was called with THREAD_ATTACH. - */ -static int g_attachCount = 0; - -/* standard DllMain() */ -BOOL PALAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved) -{ - switch( reason ) - { - case DLL_PROCESS_ATTACH: - { - g_attachCount++; - break; - } - - case DLL_PROCESS_DETACH: - { - break; - } - - case DLL_THREAD_ATTACH: - { - break; - } - - case DLL_THREAD_DETACH: - { - break; - } - } - - return TRUE; -} - -#if _WIN32 -BOOL PALAPI _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved) -{ - return DllMain(hinstDLL, reason, lpvReserved); -} -#endif - - - -/* function to return the current attach count */ -#if _WIN32 -__declspec(dllexport) -#endif -int PALAPI GetAttachCount( void ) -{ - return g_attachCount; -} - diff --git a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test6/loadlibrarya.cpp b/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test6/loadlibrarya.cpp deleted file mode 100644 index e8db6ca4bccc7c..00000000000000 --- a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test6/loadlibrarya.cpp +++ /dev/null @@ -1,169 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================= -** -** Source: loadlibrary.c (test 6) -** -** Purpose: Positive test the LoadLibrary API. Test will verify -** that it is unable to load the library twice. Once by -** using the full path name and secondly by using the -** short name. -** - -** -**============================================================*/ -#include - -/*Define platform specific information*/ -#if defined(SHLEXT) -#define LibraryName "dlltest"SHLEXT -#define GETATTACHCOUNTNAME "GetAttachCount" -#else -typedef int (*dllfunct)(); -#define LibraryName "dlltest.dll" -#define GETATTACHCOUNTNAME "_GetAttachCount@0" -#endif - -/* Helper function to test the loaded library. - */ -BOOL PALAPI TestDll(HMODULE hLib) -{ - int RetVal; - char FunctName[] = GETATTACHCOUNTNAME; - FARPROC DllFunc; - - /* Access a function from the loaded library. - */ - DllFunc = GetProcAddress(hLib, FunctName); - if(DllFunc == NULL) - { - Trace("ERROR: Unable to load function \"%s\" from library \"%s\"\n", - FunctName, - LibraryName); - return (FALSE); - } - - /* Verify that the DLL_PROCESS_ATTACH is only - * accessed once.*/ - RetVal = DllFunc(); - if (RetVal != 1) - { - Trace("ERROR: Unable to receive correct information from DLL! " - ":expected \"1\", returned \"%d\"\n", - RetVal); - return (FALSE); - } - - return (TRUE); -} - -PALTEST(loader_LoadLibraryA_test6_paltest_loadlibrarya_test6, "loader/LoadLibraryA/test6/paltest_loadlibrarya_test6") -{ - HANDLE hFullLib; - HANDLE hShortLib; - int iRetVal = FAIL; - char fullPath[_MAX_DIR]; - char drive[_MAX_DRIVE]; - char dir[_MAX_DIR]; - char fname[_MAX_FNAME]; - char ext[_MAX_EXT]; - - - - /* Initialize the PAL. */ - if ((PAL_Initialize(argc, argv)) != 0) - { - return (FAIL); - } - - /* Initialize the buffer. - */ - memset(fullPath, 0, _MAX_DIR); - - /* Get the full path to the library (DLL). - */ - - if (NULL != realpath(argv[0],fullpath)) { - - _splitpath(fullPath,drive,dir,fname,ext); - _makepath(fullPath,drive,dir,LibraryName,""); - - - } else { - Fail("ERROR: conversion from relative path \" %s \" to absolute path failed. realpath returned NULL\n",argv[0]); - } - - /* Call Load library with the short name of - * the dll. - */ - hShortLib = LoadLibrary(LibraryName); - if(hShortLib == NULL) - { - Fail("ERROR:%u:Unable to load library %s\n", - GetLastError(), - LibraryName); - } - - /* Test the loaded library. - */ - if (!TestDll(hShortLib)) - { - iRetVal = FAIL; - goto cleanUpOne; - } - - /* Call Load library with the full name of - * the dll. - */ - hFullLib = LoadLibrary(fullPath); - if(hFullLib == NULL) - { - Trace("ERROR:%u:Unable to load library %s\n", - GetLastError(), - fullPath); - iRetVal = FAIL; - goto cleanUpTwo; - } - - /* Test the loaded library. - */ - if (!TestDll(hFullLib)) - { - iRetVal = FAIL; - goto cleanUpTwo; - } - - /* Test Succeeded. - */ - iRetVal = PASS; - -cleanUpTwo: - - /* Call the FreeLibrary API. - */ - if (!FreeLibrary(hFullLib)) - { - Trace("ERROR:%u: Unable to free library \"%s\"\n", - GetLastError(), - fullPath); - iRetVal = FAIL; - } - -cleanUpOne: - - /* Call the FreeLibrary API. - */ - if (!FreeLibrary(hShortLib)) - { - Trace("ERROR:%u: Unable to free library \"%s\"\n", - GetLastError(), - LibraryName); - iRetVal = FAIL; - } - - /* Terminate the PAL. - */ - PAL_TerminateEx(iRetVal); - return iRetVal; -} diff --git a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test7/LoadLibraryA.cpp b/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test7/LoadLibraryA.cpp deleted file mode 100644 index 1ad2a754fd60e7..00000000000000 --- a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test7/LoadLibraryA.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================= -** -** Source: loadlibrarya.c -** -** Purpose: Positive test the LoadLibrary API by calling it multiple times. -** Call LoadLibrary to map a module into the calling -** process address space(DLL file) -** -** -**============================================================*/ -#include - -/* SHLEXT is defined only for Unix variants */ - -#if defined(SHLEXT) -#define ModuleName "librotor_pal"SHLEXT -#else -#define ModuleName "rotor_pal.dll" -#endif - -PALTEST(loader_LoadLibraryA_test7_paltest_loadlibrarya_test7, "loader/LoadLibraryA/test7/paltest_loadlibrarya_test7") -{ - HMODULE ModuleHandle; - HMODULE ReturnHandle; - int err; - - /* Initialize the PAL environment */ - err = PAL_Initialize(argc, argv); - if(0 != err) - { - ExitProcess(FAIL); - } - - /* load a module */ - ModuleHandle = LoadLibraryExA(ModuleName, NULL, 0); - if(!ModuleHandle) - { - Fail("Error[%u]:Failed to call LoadLibrary API!\n", GetLastError()); - } - - /* Call LoadLibrary again, should return same handle as returned for first time */ - ReturnHandle = LoadLibraryExA(ModuleName, NULL, 0); - if(!ReturnHandle) - { - Fail("Error[%u]:Failed to call LoadLibrary API second time!\n", GetLastError()); - } - - if(ModuleHandle != ReturnHandle) - { - Fail("Error[%u]:Failed to return the same handle while calling LoadLibrary API twice!\n", GetLastError()); - } - - Trace("Value of handle ModuleHandle[%x], ReturnHandle[%x]\n", ModuleHandle, ReturnHandle); - /* decrement the reference count of the loaded dll */ - err = FreeLibrary(ModuleHandle); - - if(0 == err) - { - Fail("Error[%u]:Failed to FreeLibrary API!\n", GetLastError()); - } - - /* Try Freeing a library again, should not fail */ - err = FreeLibrary(ReturnHandle); - - if(0 == err) - { - Fail("Error[%u][%d]: Was not successful in freeing a Library twice using FreeLibrary!\n", GetLastError(), err); - } - - /* Try Freeing a library again, should fail */ - err = FreeLibrary(ReturnHandle); - - if(1 != err) - { - Fail("Error[%u][%d]: Was successful in freeing a Library thrice using FreeLibrary!\n", GetLastError(), err); - } - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.cpp b/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.cpp deleted file mode 100644 index 6e2cdeb7c9a715..00000000000000 --- a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: dllmain.c -** -** Purpose: Test to ensure DllMain() is called with DLL_THREAD_DETACH -** only the initial time that the library is loaded. -** -** Depends: None -** - -** -**===========================================================================*/ - -#include - -/* count of the number of times DllMain() - * was called with THREAD_ATTACH. - */ -static int g_attachCount = 0; - -/* standard DllMain() */ -BOOL PALAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved) -{ - switch( reason ) - { - case DLL_PROCESS_ATTACH: - { - g_attachCount++; - break; - } - - case DLL_PROCESS_DETACH: - { - break; - } - - case DLL_THREAD_ATTACH: - { - break; - } - - case DLL_THREAD_DETACH: - { - break; - } - } - - return TRUE; -} - -#if _WIN32 -BOOL PALAPI _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved) -{ - return DllMain(hinstDLL, reason, lpvReserved); -} -#endif - - - -/* function to return the current attach count */ -#if _WIN32 -__declspec(dllexport) -#endif -int PALAPI GetAttachCount( void ) -{ - return g_attachCount; -} - diff --git a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test8/loadlibrarya.cpp b/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test8/loadlibrarya.cpp deleted file mode 100644 index 3276bc5a703808..00000000000000 --- a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test8/loadlibrarya.cpp +++ /dev/null @@ -1,231 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================= -** -** Source: loadlibrary.c (test 8) -** -** Purpose: Positive test the LoadLibrary API. Test will verify -** that it is unable to load the library twice. Once by -** using the full path name and secondly by using the -** short name. -** - -** -**============================================================*/ -#include - -/*Define platform specific information*/ -#if defined(SHLEXT) -#define LibraryName "dlltest"SHLEXT -#define GETATTACHCOUNTNAME "GetAttachCount" -#else -typedef int (*dllfunct)(); -#define LibraryName "dlltest.dll" -#define GETATTACHCOUNTNAME "_GetAttachCount@0" -#endif - -/* Helper function to test the loaded library. - */ -BOOL PALAPI TestDll(HMODULE hLib) -{ - int RetVal; - char FunctName[] = GETATTACHCOUNTNAME; - FARPROC DllFunc; - - /* Access a function from the loaded library. - */ - DllFunc = GetProcAddress(hLib, FunctName); - if(DllFunc == NULL) - { - Trace("ERROR: Unable to load function \"%s\" from library \"%s\"\n", - FunctName, - LibraryName); - return (FALSE); - } - - /* Verify that the DLL_PROCESS_ATTACH is only - * accessed once.*/ - RetVal = DllFunc(); - if (RetVal != 1) - { - Trace("ERROR: Unable to receive correct information from DLL! " - ":expected \"1\", returned \"%d\"\n", - RetVal); - return (FALSE); - } - - return (TRUE); -} - -PALTEST(loader_LoadLibraryA_test8_paltest_loadlibrarya_test8, "loader/LoadLibraryA/test8/paltest_loadlibrarya_test8") -{ - HANDLE hFullLib; - HANDLE hShortLib; - HANDLE hRelLib; - - int iRetVal = FAIL; - char fullPath[_MAX_DIR]; - char drive[_MAX_DRIVE]; - char dir[_MAX_DIR]; - char relTestDir[_MAX_DIR]; - char fname[_MAX_FNAME]; - char ext[_MAX_EXT]; - - BOOL bRc = FALSE; - char relLibPath[_MAX_DIR]; - - - /* Initialize the PAL. */ - if ((PAL_Initialize(argc, argv)) != 0) - { - return (FAIL); - } - - /* Initialize the buffer. - */ - memset(fullPath, 0, _MAX_DIR); - - /* Get the full path to the library (DLL). - */ - - if (NULL != realpath(argv[0],fullpath)) { - - _splitpath(fullPath,drive,dir,fname,ext); - _makepath(fullPath,drive,dir,LibraryName,""); - - - } else { - Fail("ERROR: conversion from relative path \" %s \" to absolute path failed. realpath returned NULL\n",argv[0]); - } - - /* Get relative path to the library - */ - _splitpath(argv[0], drive, relTestDir, fname, ext); - _makepath(relLibPath,drive,relTestDir,LibraryName,""); - - - /* Call Load library with the short name of - * the dll. - */ - hShortLib = LoadLibrary(LibraryName); - if(hShortLib == NULL) - { - Fail("ERROR:%u:Short:Unable to load library %s\n", - GetLastError(), - LibraryName); - } - - /* Test the loaded library. - */ - if (!TestDll(hShortLib)) - { - iRetVal = FAIL; - goto cleanUpOne; - } - - /* Call Load library with the full name of - * the dll. - */ - hFullLib = LoadLibrary(fullPath); - if(hFullLib == NULL) - { - Trace("ERROR:%u:Full:Unable to load library %s\n", - GetLastError(), - fullPath); - iRetVal = FAIL; - goto cleanUpTwo; - } - - /* Test the loaded library. - */ - if (!TestDll(hFullLib)) - { - iRetVal = FAIL; - goto cleanUpTwo; - } - - /* - ** Call the load library with the relative path - ** wrt to the directory ./testloadlibrary/.. - ** since we don't want to make any assumptions - ** regarding the type of build - */ - hRelLib = LoadLibrary(relLibPath); - if(hRelLib == NULL) - { - Trace("ERROR:%u:Rel:Unable to load library at %s\n", - GetLastError(), relLibPath); - iRetVal = FAIL; - goto cleanUpTwo; - } - - /* Test the loaded library. - */ - if (!TestDll(hRelLib)) - { - iRetVal = FAIL; - goto cleanUpThree; - } - - if( hRelLib != hFullLib ) - { - Trace("Relative and Absolute Paths to libraries don't have same handle\n"); - iRetVal = FAIL; - goto cleanUpThree; - } - - if( hRelLib != hShortLib ) - { - Trace("Relative and Short Paths to libraries don't have same handle\n"); - iRetVal = FAIL; - goto cleanUpThree; - } - - - /* Test Succeeded. - */ - iRetVal = PASS; - -cleanUpThree: - - /* Call the FreeLibrary API. - */ - - if (!FreeLibrary(hRelLib)) - { - Trace("ERROR:%u: Unable to free library \"%s\"\n", - GetLastError(), - relLibPath); - iRetVal = FAIL; - } - -cleanUpTwo: - - /* Call the FreeLibrary API. - */ - if (!FreeLibrary(hFullLib)) - { - Trace("ERROR:%u: Unable to free library \"%s\"\n", - GetLastError(), - fullPath); - iRetVal = FAIL; - } - -cleanUpOne: - - /* Call the FreeLibrary API. - */ - if (!FreeLibrary(hShortLib)) - { - Trace("ERROR:%u: Unable to free library \"%s\"\n", - GetLastError(), - LibraryName); - iRetVal = FAIL; - } - - /* Terminate the PAL. - */ - PAL_TerminateEx(iRetVal); - return iRetVal; -} diff --git a/src/coreclr/pal/tests/palsuite/locale_info/CompareStringA/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/locale_info/CompareStringA/test1/test1.cpp deleted file mode 100644 index 91d4ae9da3ca74..00000000000000 --- a/src/coreclr/pal/tests/palsuite/locale_info/CompareStringA/test1/test1.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Tests that CompareStringA returns the correct value and can handle -** invalid parameters. -** -** -**==========================================================================*/ - -#define CSTR_LESS_THAN 1 -#define CSTR_EQUAL 2 -#define CSTR_GREATER_THAN 3 - -#include - -PALTEST(locale_info_CompareStringA_test1_paltest_comparestringa_test1, "locale_info/CompareStringA/test1/paltest_comparestringa_test1") -{ - char str1[] = {'f','o','o',0}; - char str2[] = {'f','o','o','x',0}; - char str3[] = {'f','O','o',0}; - int flags = NORM_IGNORECASE | NORM_IGNOREWIDTH; - int ret; - - if (0 != PAL_Initialize(argc, argv)) - { - return FAIL; - } - - ret = CompareStringA(0x0409, flags, str1, -1, str2, -1); - if (ret != CSTR_LESS_THAN) - { - Fail("CompareStringA with \"%S\" (%d) and \"%S\" (%d) did not return " - "CSTR_LESS_THAN!\n", str1, -1, str2, -1); - } - - ret = CompareStringA(0x0409, flags, str1, -1, str2, 3); - if (ret != CSTR_EQUAL) - { - Fail("CompareStringA with \"%S\" (%d) and \"%S\" (%d) did not return " - "CSTR_EQUAL!\n", str1, -1, str2, 3); - } - - ret = CompareStringA(0x0409, flags, str2, -1, str1, -1); - if (ret != CSTR_GREATER_THAN) - { - Fail("CompareStringA with \"%S\" (%d) and \"%S\" (%d) did not return " - "CSTR_GREATER_THAN!\n", str2, -1, str1, -1); - } - - ret = CompareStringA(0x0409, flags, str1, -1, str3, -1); - if (ret != CSTR_EQUAL) - { - Fail("CompareStringA with \"%S\" (%d) and \"%S\" (%d) did not return " - "CSTR_EQUAL!\n", str1, -1, str3, -1); - } - - ret = CompareStringA(0x0409, flags, str3, -1, str1, -1); - if (ret != CSTR_EQUAL) - { - Fail("CompareStringA with \"%S\" (%d) and \"%S\" (%d) did not return " - "CSTR_EQUAL!\n", str3, -1, str1, -1); - } - - ret = CompareStringA(0x0409, flags, str3, -1, str1, -1); - if (ret != CSTR_EQUAL) - { - Fail("CompareStringA with \"%S\" (%d) and \"%S\" (%d) did not return " - "CSTR_EQUAL!\n", str3, -1, str1, -1); - } - - ret = CompareStringA(0x0409, flags, str1, 0, str3, -1); - if (ret != CSTR_LESS_THAN) - { - Fail("CompareStringA with \"%S\" (%d) and \"%S\" (%d) did not return " - "CSTR_GREATER_THAN!\n", str1, 0, str3, -1); - } - - - ret = CompareStringA(0x0409, flags, NULL, -1, str3, -1); - if (ret != 0) - { - Fail("CompareStringA should have returned 0, got %d!\n", ret); - } - if (GetLastError() != ERROR_INVALID_PARAMETER) - { - Fail("CompareStringA should have set the last error to " - "ERROR_INVALID_PARAMETER!\n"); - } - - PAL_Terminate(); - - return PASS; -} - diff --git a/src/coreclr/pal/tests/palsuite/locale_info/CompareStringW/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/locale_info/CompareStringW/test1/test1.cpp deleted file mode 100644 index d15094609a9959..00000000000000 --- a/src/coreclr/pal/tests/palsuite/locale_info/CompareStringW/test1/test1.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Tests that CompareStringW returns the correct value and can handle -** invalid parameters. -** -** -**==========================================================================*/ - -#define CSTR_LESS_THAN 1 -#define CSTR_EQUAL 2 -#define CSTR_GREATER_THAN 3 - -#include - -PALTEST(locale_info_CompareStringW_test1_paltest_comparestringw_test1, "locale_info/CompareStringW/test1/paltest_comparestringw_test1") -{ - WCHAR str1[] = {'f','o','o',0}; - WCHAR str2[] = {'f','o','o','x',0}; - WCHAR str3[] = {'f','O','o',0}; - int flags = NORM_IGNORECASE | NORM_IGNOREWIDTH; - int ret; - - if (0 != PAL_Initialize(argc, argv)) - { - return FAIL; - } - - ret = CompareStringW(0x0409, flags, str1, -1, str2, -1); - if (ret != CSTR_LESS_THAN) - { - Fail("CompareStringW with \"%S\" (%d) and \"%S\" (%d) did not return " - "CSTR_LESS_THAN!\n", str1, -1, str2, -1); - } - - ret = CompareStringW(0x0409, flags, str1, -1, str2, 3); - if (ret != CSTR_EQUAL) - { - Fail("CompareStringW with \"%S\" (%d) and \"%S\" (%d) did not return " - "CSTR_EQUAL!\n", str1, -1, str2, 3); - } - - ret = CompareStringW(0x0409, flags, str2, -1, str1, -1); - if (ret != CSTR_GREATER_THAN) - { - Fail("CompareStringW with \"%S\" (%d) and \"%S\" (%d) did not return " - "CSTR_GREATER_THAN!\n", str2, -1, str1, -1); - } - - ret = CompareStringW(0x0409, flags, str1, -1, str3, -1); - if (ret != CSTR_EQUAL) - { - Fail("CompareStringW with \"%S\" (%d) and \"%S\" (%d) did not return " - "CSTR_EQUAL!\n", str1, -1, str3, -1); - } - - ret = CompareStringW(0x0409, flags, str3, -1, str1, -1); - if (ret != CSTR_EQUAL) - { - Fail("CompareStringW with \"%S\" (%d) and \"%S\" (%d) did not return " - "CSTR_EQUAL!\n", str3, -1, str1, -1); - } - - ret = CompareStringW(0x0409, flags, str3, -1, str1, -1); - if (ret != CSTR_EQUAL) - { - Fail("CompareStringW with \"%S\" (%d) and \"%S\" (%d) did not return " - "CSTR_EQUAL!\n", str3, -1, str1, -1); - } - - ret = CompareStringW(0x0409, flags, str1, 0, str3, -1); - if (ret != CSTR_LESS_THAN) - { - Fail("CompareStringW with \"%S\" (%d) and \"%S\" (%d) did not return " - "CSTR_GREATER_THAN!\n", str1, 0, str3, -1); - } - - - ret = CompareStringW(0x0409, flags, NULL, -1, str3, -1); - if (ret != 0) - { - Fail("CompareStringW should have returned 0, got %d!\n", ret); - } - if (GetLastError() != ERROR_INVALID_PARAMETER) - { - Fail("CompareStringW should have set the last error to " - "ERROR_INVALID_PARAMETER!\n"); - } - - PAL_Terminate(); - - return PASS; -} - diff --git a/src/coreclr/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/test1.cpp deleted file mode 100644 index ea9cbb331c101b..00000000000000 --- a/src/coreclr/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/test1.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================ -** -** Source: test1.c -** -** Purpose: Tests that GetLocaleInfoW gives the correction information for -** LOCALE_NEUTRAL. -** -** -**==========================================================================*/ - -#include - - -int Types[] = { LOCALE_SDECIMAL, LOCALE_STHOUSAND, LOCALE_ILZERO, - LOCALE_SCURRENCY, LOCALE_SMONDECIMALSEP, LOCALE_SMONTHOUSANDSEP }; - -char *TypeStrings[] = { "LOCALE_SDECIMAL", "LOCALE_STHOUSAND", "LOCALE_ILZERO", - "LOCALE_SCURRENCY", "LOCALE_SMONDECIMALSEP", "LOCALE_SMONTHOUSANDSEP" }; - -typedef WCHAR InfoStrings[ARRAY_SIZE(Types)][4]; - -typedef struct -{ - LCID lcid; - InfoStrings Strings; -} LocalInfoType; - -LocalInfoType Locales[] = -{ - {LOCALE_NEUTRAL, - {{'.',0}, {',',0}, {'1',0}, {'$',0}, {'.',0}, {',',0}}}, -}; - -int NumLocales = sizeof(Locales) / sizeof(Locales[0]); - - -PALTEST(locale_info_GetLocaleInfoW_test1_paltest_getlocaleinfow_test1, "locale_info/GetLocaleInfoW/test1/paltest_getlocaleinfow_test1") -{ - WCHAR buffer[256] = { 0 }; - int ret; - int i,j; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - for (i=0; i - -PALTEST(locale_info_GetLocaleInfoW_test2_paltest_getlocaleinfow_test2, "locale_info/GetLocaleInfoW/test2/paltest_getlocaleinfow_test2") -{ - WCHAR buffer[256] = { 0 }; - int ret; - - if (PAL_Initialize(argc, argv)) - { - return FAIL; - } - - ret = GetLocaleInfoW(LOCALE_NEUTRAL, LOCALE_SDECIMAL, buffer, 0); - if (ret != 2) - { - Fail("GetLocaleInfoW gave incorrect desired length for buffer.\n" - "Expected 2, got %d.\n", ret); - } - - ret = GetLocaleInfoW(LOCALE_NEUTRAL, LOCALE_SDECIMAL, buffer, 1); - if (ret != 0) - { - Fail("GetLocaleInfoW expected to return 0, returned %d", ret); - } - - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - { - Fail("GetLocaleInfoW failed to set last error to " - "ERROR_INSUFFICIENT_BUFFER!\n"); - } - - PAL_Terminate(); - - return PASS; -} - diff --git a/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/test1.cpp deleted file mode 100644 index c3d4fe70c578c1..00000000000000 --- a/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/test1.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================================= -** -** Source: test1.c -** -** Purpose: Test to ensure that IsBadCodePtr return 0 when -** it can read memory or non zero when it can't. -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** - -** -**===========================================================================*/ - -#include - -/** - * main - * - * executable entry point - */ -PALTEST(miscellaneous_IsBadCodePtr_test1_paltest_isbadcodeptr_test1, "miscellaneous/IsBadCodePtr/test1/paltest_isbadcodeptr_test1") -{ - BOOL ResultValue = 0; - - /* - * Initialize the PAL and return FAILURE if this fails - */ - - if(0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - /* This should be readable, and return 0 */ - ResultValue = IsBadCodePtr((FARPROC)main); - if(ResultValue != 0) - { - Fail("ERROR: IsBadCodePtr returned %d instead of 0, when pointing " - "at readable memory.\n",ResultValue); - } - - /* 0x00 is usually unreadable memory so the function should - return non zero */ - ResultValue = IsBadCodePtr((FARPROC)0x00); - - if(ResultValue == 0) - { - Fail("ERROR: IsBadCodePtr returned %d instead of non zero " - "when checking on unreadable memory.\n",ResultValue); - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/test.cpp b/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/test.cpp deleted file mode 100644 index b0a2ab1762db76..00000000000000 --- a/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/test.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================ -** -** Source: test.c -** -** Purpose: IsBadReadPtr() function -** -** -**=========================================================*/ - -#include -#include - -#define MEMORY_AMOUNT 16 - -PALTEST(miscellaneous_IsBadReadPtr_test1_paltest_isbadreadptr_test1, "miscellaneous/IsBadReadPtr/test1/paltest_isbadreadptr_test1") -{ - LPVOID TestingPointer = NULL; - BOOL ResultValue = 0; - - /* - * Initialize the PAL and return FAILURE if this fails - */ - - if(0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - TestingPointer = malloc(MEMORY_AMOUNT); - if ( TestingPointer == NULL ) - { - Fail("ERROR: Failed to allocate memory for TestingPointer pointer. " - "Can't properly exec test case without this."); - } - - - /* This should be readable, and return 0 */ - ResultValue = IsBadReadPtr(TestingPointer,MEMORY_AMOUNT); - if(ResultValue != 0) - { - free(TestingPointer); - - Fail("ERROR: The function returned %d instead of 0, when pointing " - "at readable memory.",ResultValue); - } - - /* If we pass 0, the result should be 0 as well */ - ResultValue = IsBadReadPtr(TestingPointer,0); - if(ResultValue != 0) - { - free(TestingPointer); - - Fail("ERROR: The function returned %d instead of 0, when the " - "function was passed a range of 0 bytes.",ResultValue); - } - free(TestingPointer); /* we are done with this */ - - /* create a readable address */ - TestingPointer = mmap(NULL, 80, PROT_READ, MAP_ANON | MAP_PRIVATE, -1, 0); - - if (TestingPointer == MAP_FAILED ) - { - Fail("ERROR: call to mmap failed"); - } - - ResultValue = IsBadReadPtr(TestingPointer,16); - if(ResultValue != 0) - { - munmap(TestingPointer, 80); - - Fail("ERROR: The function returned %d instead of 1 when checking " - "on unreadable memory.",ResultValue); - } - - munmap(TestingPointer, 80); - - /* create an unreadable address */ - TestingPointer = mmap(NULL, 80, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0); - - if (TestingPointer == MAP_FAILED ) - { - Fail("ERROR: call to mmap failed"); - } - - ResultValue = IsBadReadPtr(TestingPointer,16); - - if(ResultValue == 0) - { - munmap(TestingPointer, 80); - - Fail("ERROR: The function returned %d instead of 1 when checking " - "on unreadable memory.",ResultValue); - } - - munmap(TestingPointer, 80); - - - /* This should be unreadable and return 1 */ - ResultValue = IsBadReadPtr(NULL,16); - if(ResultValue != 1) - { - Fail("ERROR: The function returned %d instead of 1 when checking " - "to see if NULL was readable.",ResultValue); - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/test.cpp b/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/test.cpp deleted file mode 100644 index 64bd8022313fa7..00000000000000 --- a/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/test.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================ -** -** Source: test.c -** -** Purpose: IsBadWritePtr() function -** -** -**=========================================================*/ - -#include - -#define MEMORY_AMOUNT 16 - -PALTEST(miscellaneous_IsBadWritePtr_test1_paltest_isbadwriteptr_test1, "miscellaneous/IsBadWritePtr/test1/paltest_isbadwriteptr_test1") -{ - - void * TestingPointer = NULL; - BOOL ResultValue = 0; - - /* - * Initialize the PAL and return FAILURE if this fails - */ - - if(0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - TestingPointer = malloc(MEMORY_AMOUNT); - if ( TestingPointer == NULL ) - { - Fail("ERROR: Failed to allocate memory for TestingPointer pointer. " - "Can't properly exec test case without this.\n"); - } - - - /* This should be writeable, return 0 */ - ResultValue = IsBadWritePtr(TestingPointer,MEMORY_AMOUNT); - - if(ResultValue != 0) - { - free(TestingPointer); - - Fail("ERROR: Returned %d when 0 should have been returned, checking " - "to see if writable memory is unwriteable.\n",ResultValue); - } - - free(TestingPointer); - - /* This should be !writeable, return nonezero */ - TestingPointer = (void*)0x08; /* non writeable address */ - ResultValue = IsBadWritePtr(TestingPointer,sizeof(int)); - - if(ResultValue == 0) - { - Fail("ERROR: Returned %d when nonezero should have been returned, " - "checking to see if unwriteable memory is writeable.\n", - ResultValue); - } - - /* This should be !writeable, return Nonezero */ - ResultValue = IsBadWritePtr(NULL,MEMORY_AMOUNT); - - if(ResultValue == 0) - { - Fail("ERROR: Returned %d when nonezero should have been " - "returned,checking " - "to see if a NULL pointer is writeable.\n", - ResultValue); - } - - PAL_Terminate(); - return PASS; -} - - - - diff --git a/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/test2.cpp b/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/test2.cpp deleted file mode 100644 index 82bf114eb63012..00000000000000 --- a/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/test2.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================ -** -** Source: test2.c -** -** Purpose: -** Create three consecutive pages, NOACCESS, READWRITE and -** NOACCESS. Check to ensure that the READWRITE page returns 0, to -** ensure that IsBadWritePtr isn't overflowing. Also check the other two -** pages to see that they return non-zero. -** -** -**=========================================================*/ - -#include -#include -#include - -PALTEST(miscellaneous_IsBadWritePtr_test2_paltest_isbadwriteptr_test2, "miscellaneous/IsBadWritePtr/test2/paltest_isbadwriteptr_test2") -{ - BYTE* baseAddress; - LPVOID PageOne; - LPVOID PageTwo; - LPVOID PageThree; - size_t pageSize = minipal_getpagesize(); - - if(0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - baseAddress = static_cast(mmap(NULL, pageSize * 4, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0)); - if(baseAddress == MAP_FAILED) - { - Fail("ERROR: mmap failed to reserve the required memory."); - } - - PageOne = baseAddress; - PageTwo = baseAddress + pageSize; - PageThree = baseAddress + (2 * pageSize); - - if(mprotect(PageTwo, pageSize, PROT_READ | PROT_WRITE) != 0) - { - munmap(baseAddress, pageSize * 4); - Fail("ERROR: mprotect failed to make the middle page writable."); - } - - if(IsBadWritePtr(PageOne,pageSize) == 0) - { - munmap(baseAddress, pageSize * 4); - - Fail("ERROR: Called IsBadWritePtr on a page which was set NOACCESS " - "but the return value was 0, indicating that the memory is " - "writable."); - } - - if(IsBadWritePtr(PageTwo,pageSize) != 0) - { - munmap(baseAddress, pageSize * 4); - - Fail("ERROR: IsBadWritePtr didn't return 0 when called on a " - "page which should have been writable."); - } - - if(IsBadWritePtr(PageThree,pageSize) == 0) - { - munmap(baseAddress, pageSize * 4); - - Fail("ERROR: Called IsBadWritePtr on a page which was set NOACCESS " - "but the return value was 0, indicating that the memory is " - "writable."); - } - - munmap(baseAddress, pageSize * 4); - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/test3.cpp b/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/test3.cpp deleted file mode 100644 index 524682eb6845ee..00000000000000 --- a/src/coreclr/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/test3.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================ -** -** Source: test3.c -** -** Purpose: -** Check that IsBadWritePtr returns non-zero on Read-only memory. -** -** -**=========================================================*/ - -#include -#include -#include - -PALTEST(miscellaneous_IsBadWritePtr_test3_paltest_isbadwriteptr_test3, "miscellaneous/IsBadWritePtr/test3/paltest_isbadwriteptr_test3") -{ - LPVOID PageOne; - size_t pageSize = minipal_getpagesize(); - - if(0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - PageOne = mmap(NULL, pageSize, PROT_READ, MAP_ANON | MAP_PRIVATE, -1, 0); - - if(PageOne == MAP_FAILED) - { - Fail("ERROR: mmap failed to create the required read-only memory."); - } - - if(IsBadWritePtr(PageOne,pageSize) == 0) - { - munmap(PageOne, pageSize); - - Fail("ERROR: IsBadWritePtr returned 0 when checking a section of " - "read-only memory. It should be non-zero."); - } - - munmap(PageOne, pageSize); - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/PAL_RegisterLibraryW_UnregisterLibraryW.cpp b/src/coreclr/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/PAL_RegisterLibraryW_UnregisterLibraryW.cpp deleted file mode 100644 index 0eab8ece1ff095..00000000000000 --- a/src/coreclr/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/PAL_RegisterLibraryW_UnregisterLibraryW.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================= -** -** Source: pal_registerlibrary_unregisterlibrary -** -** Purpose: Positive test the PAL_RegisterLibrary API and -** PAL_UnRegisterLibrary. -** Call PAL_RegisterLibrary to map a module into the calling -** process address space and call PAL_UnRegisterLibrary -** to unmap this module. -** -** -**============================================================*/ -#define UNICODE -#include - -PALTEST(pal_specific_PAL_RegisterLibraryW_UnregisterLibraryW_test1_paltest_pal_registerlibraryw_unregisterlibraryw_test1, "pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/paltest_pal_registerlibraryw_unregisterlibraryw_test1") -{ - HMODULE ModuleHandle; - char ModuleName[64]; - WCHAR *wpModuleName = NULL; - int err; - - /*Initialize the PAL environment*/ - err = PAL_Initialize(argc, argv); - if(0 != err) - { - return FAIL; - } - - /*zero the buffer*/ - memset(ModuleName,0,64); - sprintf_s(ModuleName, ARRAY_SIZE(ModuleName), "%s", "rotor_pal"); - - /*convert a normal string to a wide one*/ - wpModuleName = convert(ModuleName); - - /*load a module*/ - ModuleHandle = PAL_RegisterLibrary(wpModuleName); - - /*free the memory*/ - free(wpModuleName); - - if(!ModuleHandle) - { - Fail("Failed to call PAL_RegisterLibrary API to map a module " - "into calling process, error code=%u!\n", GetLastError()); - } - - /*decrement the reference count of the loaded DLL*/ - err = PAL_UnregisterLibrary(ModuleHandle); - if(0 == err) - { - Fail("\nFailed to call PAL_UnregisterLibrary API to " - "decrement the count of the loaded DLL module, " - "error code=%u!\n", GetLastError()); - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/reg_unreg_libraryw_neg.cpp b/src/coreclr/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/reg_unreg_libraryw_neg.cpp deleted file mode 100644 index 4d34414e72c26a..00000000000000 --- a/src/coreclr/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/reg_unreg_libraryw_neg.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================= -** -** Source: pal_registerlibraryw_unregisterlibraryw_neg.c -** -** Purpose: Negative test the PAL_RegisterLibrary API. -** Call PAL_RegisterLibrary to map a non-existent module -** into the calling process address space. -** -** -**============================================================*/ -#define UNICODE -#include - -PALTEST(pal_specific_PAL_RegisterLibraryW_UnregisterLibraryW_test2_neg_paltest_reg_unreg_libraryw_neg, "pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/paltest_reg_unreg_libraryw_neg") -{ - HMODULE ModuleHandle; - char ModuleName[64]; - WCHAR *wpModuleName = NULL; - int err; - - /*Initialize the PAL environment*/ - err = PAL_Initialize(argc, argv); - if(0 != err) - { - return FAIL; - } - - memset(ModuleName, 0, 64); - sprintf_s(ModuleName, ARRAY_SIZE(ModuleName), "%s", "not_exist_module_name"); - - /*convert a normal string to a wide one*/ - wpModuleName = convert(ModuleName); - - /*load a not exist module*/ - ModuleHandle = PAL_RegisterLibrary(wpModuleName); - - /*free the memory*/ - free(wpModuleName); - - if(NULL != ModuleHandle) - { - Trace("ERROR: PAL_RegisterLibrary successfully mapped " - "a module that does not exist into the calling process\n"); - - /*decrement the reference count of the loaded DLL*/ - err = PAL_UnregisterLibrary(ModuleHandle); - if(0 == err) - { - Trace("\nFailed to call PAL_UnregisterLibrary API to decrement the " - "count of the loaded DLL module!\n"); - } - Fail(""); - - } - - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/paltestlist.txt b/src/coreclr/pal/tests/palsuite/paltestlist.txt index 4c46b065fa2165..b348aa0e5fdb26 100644 --- a/src/coreclr/pal/tests/palsuite/paltestlist.txt +++ b/src/coreclr/pal/tests/palsuite/paltestlist.txt @@ -1,19 +1,3 @@ -c_runtime/atof/test1/paltest_atof_test1 -c_runtime/atoi/test1/paltest_atoi_test1 -c_runtime/isalnum/test1/paltest_isalnum_test1 -c_runtime/isalpha/test1/paltest_isalpha_test1 -c_runtime/isdigit/test1/paltest_isdigit_test1 -c_runtime/isprint/test1/paltest_isprint_test1 -c_runtime/isprint/test2/paltest_isprint_test2 -c_runtime/isspace/test1/paltest_isspace_test1 -c_runtime/iswdigit/test1/paltest_iswdigit_test1 -c_runtime/iswspace/test1/paltest_iswspace_test1 -c_runtime/iswupper/test1/paltest_iswupper_test1 -c_runtime/isxdigit/test1/paltest_isxdigit_test1 -c_runtime/memchr/test1/paltest_memchr_test1 -c_runtime/memcmp/test1/paltest_memcmp_test1 -c_runtime/memmove/test1/paltest_memmove_test1 -c_runtime/memset/test1/paltest_memset_test1 c_runtime/sscanf_s/test1/paltest_sscanf_test1 c_runtime/sscanf_s/test10/paltest_sscanf_test10 c_runtime/sscanf_s/test11/paltest_sscanf_test11 @@ -31,21 +15,6 @@ c_runtime/sscanf_s/test6/paltest_sscanf_test6 c_runtime/sscanf_s/test7/paltest_sscanf_test7 c_runtime/sscanf_s/test8/paltest_sscanf_test8 c_runtime/sscanf_s/test9/paltest_sscanf_test9 -c_runtime/strcat/test1/paltest_strcat_test1 -c_runtime/strchr/test1/paltest_strchr_test1 -c_runtime/strcmp/test1/paltest_strcmp_test1 -c_runtime/strcpy/test1/paltest_strcpy_test1 -c_runtime/strlen/test1/paltest_strlen_test1 -c_runtime/strncat/test1/paltest_strncat_test1 -c_runtime/strncmp/test1/paltest_strncmp_test1 -c_runtime/strncpy/test1/paltest_strncpy_test1 -c_runtime/strpbrk/test1/paltest_strpbrk_test1 -c_runtime/strrchr/test1/paltest_strrchr_test1 -c_runtime/strstr/test1/paltest_strstr_test1 -c_runtime/tolower/test1/paltest_tolower_test1 -c_runtime/toupper/test1/paltest_toupper_test1 -c_runtime/towlower/test1/paltest_towlower_test1 -c_runtime/towupper/test1/paltest_towupper_test1 c_runtime/wcscat/test1/paltest_wcscat_test1 c_runtime/wcschr/test1/paltest_wcschr_test1 c_runtime/wcscmp/test1/paltest_wcscmp_test1 @@ -63,9 +32,6 @@ c_runtime/wcstoul/test3/paltest_wcstoul_test3 c_runtime/wcstoul/test4/paltest_wcstoul_test4 c_runtime/wcstoul/test5/paltest_wcstoul_test5 c_runtime/wcstoul/test6/paltest_wcstoul_test6 -c_runtime/_alloca/test1/paltest_alloca_test1 -c_runtime/_rotl/test1/paltest_rotl_test1 -c_runtime/_rotr/test1/paltest_rotr_test1 c_runtime/_vsnprintf_s/test1/paltest_vsnprintf_test1 c_runtime/_vsnprintf_s/test10/paltest_vsnprintf_test10 c_runtime/_vsnprintf_s/test11/paltest_vsnprintf_test11 @@ -96,9 +62,6 @@ filemapping_memmgt/GetModuleFileNameA/test2/paltest_getmodulefilenamea_test2 filemapping_memmgt/GetModuleFileNameW/test2/paltest_getmodulefilenamew_test2 filemapping_memmgt/ProbeMemory/test1/paltest_probememory_test1 filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/paltest_probememory_probememory_neg1 -loader/LoadLibraryA/test2/paltest_loadlibrarya_test2 -loader/LoadLibraryA/test3/paltest_loadlibrarya_test3 -loader/LoadLibraryA/test5/paltest_loadlibrarya_test5 loader/LoadLibraryW/test2/paltest_loadlibraryw_test2 loader/LoadLibraryW/test3/paltest_loadlibraryw_test3 loader/LoadLibraryW/test5/paltest_loadlibraryw_test5 diff --git a/src/coreclr/pal/tests/palsuite/paltestlist_to_be_reviewed.txt b/src/coreclr/pal/tests/palsuite/paltestlist_to_be_reviewed.txt index 658c6acf8f2a4c..bd85a96c38855c 100644 --- a/src/coreclr/pal/tests/palsuite/paltestlist_to_be_reviewed.txt +++ b/src/coreclr/pal/tests/palsuite/paltestlist_to_be_reviewed.txt @@ -1,7 +1,6 @@ This is a list of failing PAL tests that need to be reviewed because. They should either be fixed or deleted if they are no longer applicable. -c_runtime/iswprint/test1/paltest_iswprint_test1 debug_api/DebugBreak/test1/paltest_debugbreak_test1 debug_api/OutputDebugStringA/test1/paltest_outputdebugstringa_test1 exception_handling/pal_except/test1/paltest_pal_except_test1 @@ -29,31 +28,16 @@ filemapping_memmgt/GetModuleFileNameA/test1/paltest_getmodulefilenamea_test1 filemapping_memmgt/GetModuleFileNameW/test1/paltest_getmodulefilenamew_test1 filemapping_memmgt/GetProcAddress/test1/paltest_getprocaddress_test1 filemapping_memmgt/GetProcAddress/test2/paltest_getprocaddress_test2 -loader/LoadLibraryA/test1/paltest_loadlibrarya_test1 -loader/LoadLibraryA/test6/paltest_loadlibrarya_test6 -loader/LoadLibraryA/test7/paltest_loadlibrarya_test7 -loader/LoadLibraryA/test8/paltest_loadlibrarya_test8 loader/LoadLibraryW/test1/paltest_loadlibraryw_test1 -locale_info/CompareStringA/test1/paltest_comparestringa_test1 -locale_info/CompareStringW/test1/paltest_comparestringw_test1 -locale_info/GetLocaleInfoW/test1/paltest_getlocaleinfow_test1 -locale_info/GetLocaleInfoW/test2/paltest_getlocaleinfow_test2 miscellaneous/FormatMessageW/test4/paltest_formatmessagew_test4 miscellaneous/FormatMessageW/test5/paltest_formatmessagew_test5 miscellaneous/FormatMessageW/test6/paltest_formatmessagew_test6 miscellaneous/InterLockedExchangeAdd/test1/paltest_interlockedexchangeadd_test1 -miscellaneous/IsBadCodePtr/test1/paltest_isbadcodeptr_test1 -miscellaneous/IsBadReadPtr/test1/paltest_isbadreadptr_test1 -miscellaneous/IsBadWritePtr/test1/paltest_isbadwriteptr_test1 -miscellaneous/IsBadWritePtr/test2/paltest_isbadwriteptr_test2 -miscellaneous/IsBadWritePtr/test3/paltest_isbadwriteptr_test3 pal_specific/PAL_get_stdout/test1/paltest_pal_get_stdout_test1 -pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/paltest_pal_registerlibraryw_unregisterlibraryw_test1 samples/test2/paltest_samples_test2 threading/CreateThread/test2/paltest_createthread_test2 threading/DuplicateHandle/test9/paltest_duplicatehandle_test9 threading/ExitThread/test2/paltest_exitthread_test2 threading/GetCurrentProcess/test1/paltest_getcurrentprocess_test1 threading/GetCurrentThreadId/test1/paltest_getcurrentthreadid_test1 -threading/Sleep/test1/paltest_sleep_test1 threading/TerminateProcess/test1/paltest_terminateprocess_test1 diff --git a/src/coreclr/pal/tests/palsuite/threading/Sleep/test1/Sleep.cpp b/src/coreclr/pal/tests/palsuite/threading/Sleep/test1/Sleep.cpp deleted file mode 100644 index 043cfafb0f1827..00000000000000 --- a/src/coreclr/pal/tests/palsuite/threading/Sleep/test1/Sleep.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================ -** -** Source: Sleep.c -** -** Purpose: Test to establish whether the Sleep function stops the thread from -** executing for the specified times. -** -** Dependencies: Fail -** Trace -** - -** -**=========================================================*/ - -#include - -PALTEST(threading_Sleep_test1_paltest_sleep_test1, "threading/Sleep/test1/paltest_sleep_test1") -{ - DWORD SleepTimes[] = - { - 0, - 50, - 100, - 500, - 2000 - }; - - /* Milliseconds of error which are acceptable Function execution time, etc. */ - DWORD AcceptableTimeError = 150; - - int64_t OldTimeStamp; - int64_t NewTimeStamp; - DWORD MaxDelta; - DWORD TimeDelta; - DWORD i; - - if(0 != (PAL_Initialize(argc, argv))) - { - return ( FAIL ); - } - - for( i = 0; i < sizeof(SleepTimes) / sizeof(DWORD); i++) - { - OldTimeStamp = minipal_hires_ticks(); - minipal_sleep(SleepTimes[i]); - NewTimeStamp = minipal_hires_ticks(); - - TimeDelta = (NewTimeStamp - OldTimeStamp) / (minipal_hires_tick_frequency() / 1000); - - /* For longer intervals use a 10 percent tolerance */ - if ((SleepTimes[i] * 0.1) > AcceptableTimeError) - { - MaxDelta = SleepTimes[i] + (DWORD)(SleepTimes[i] * 0.1); - } - else - { - MaxDelta = SleepTimes[i] + AcceptableTimeError; - } - - if ( TimeDeltaMaxDelta ) - { - Fail("The sleep function slept for %d ms when it should have " - "slept for %d ms\n", TimeDelta, SleepTimes[i]); - } - } - PAL_Terminate(); - return ( PASS ); - -} diff --git a/src/coreclr/pal/tests/palsuite/threading/Sleep/test2/sleep.cpp b/src/coreclr/pal/tests/palsuite/threading/Sleep/test2/sleep.cpp deleted file mode 100644 index 74edfce80962f8..00000000000000 --- a/src/coreclr/pal/tests/palsuite/threading/Sleep/test2/sleep.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================ -** -** Source: Sleep.c -** -** Purpose: Test to establish whether the Sleep function stops the thread from -** executing for the specified times. -** - -** -**=========================================================*/ - -#include - -PALTEST(threading_Sleep_test2_paltest_sleep_test2, "threading/Sleep/test2/paltest_sleep_test2") -{ - /* - * times in 10^(-3) seconds - */ - - DWORD SleepTimes[] = - { - 60000, - 300000, - 1800000, - 3200000 - }; - - /* Milliseconds of error which are acceptable Function execution time, etc. */ - DWORD AcceptableTimeError = 150; - - int64_t OldTimeStamp; - int64_t NewTimeStamp; - DWORD MaxDelta; - DWORD TimeDelta; - DWORD i; - - if(0 != (PAL_Initialize(argc, argv))) - { - return ( FAIL ); - } - - for( i = 0; i < sizeof(SleepTimes) / sizeof(DWORD); i++) - { - OldTimeStamp = minipal_hires_ticks(); - minipal_sleep(SleepTimes[i]); - NewTimeStamp = minipal_hires_ticks(); - - TimeDelta = (NewTimeStamp - OldTimeStamp) / (minipal_hires_tick_frequency() / 1000); - - MaxDelta = SleepTimes[i] + AcceptableTimeError; - - if ( TimeDeltaMaxDelta ) - { - Fail("The sleep function slept for %u ms when it should have " - "slept for %u ms\n", TimeDelta, SleepTimes[i]); - } - } - PAL_Terminate(); - return ( PASS ); - -} From 9939ca6ba8edd81675bb60cef3cf8b26e9b63327 Mon Sep 17 00:00:00 2001 From: am11 <3840695+am11@users.noreply.github.com> Date: Sat, 7 Nov 2026 22:10:49 +0200 Subject: [PATCH 11/13] Avoid size_t-to-int casts in Utf2Quick Keep conversion lengths as size_t to match the minipal APIs. Co-authored-by: Cursor --- src/coreclr/debug/daccess/daccess.cpp | 9 ++++-- src/coreclr/ilasm/assem.cpp | 8 ++--- src/coreclr/ilasm/assembler.cpp | 7 +++-- src/coreclr/jit/helperexpansion.cpp | 15 +++++---- src/coreclr/md/compiler/custattr_import.cpp | 4 +-- src/coreclr/md/compiler/import.cpp | 10 +++--- src/coreclr/md/enc/metamodelrw.cpp | 13 +++++--- src/coreclr/md/enc/stgtiggerstorage.cpp | 6 ++-- src/coreclr/md/runtime/metamodelro.cpp | 13 +++++--- src/coreclr/md/runtime/stgpool.cpp | 12 +++---- .../nativeresources/resourcestring.cpp | 8 ++--- src/coreclr/pal/src/cruntime/wchar.cpp | 18 +++++------ src/coreclr/pal/src/debug/debug.cpp | 4 +-- src/coreclr/pal/src/init/pal.cpp | 4 +-- src/coreclr/pal/src/loader/module.cpp | 9 ++++-- src/coreclr/pal/src/misc/environ.cpp | 22 +++++++------ src/coreclr/pal/src/misc/fmtmessage.cpp | 6 ++-- src/coreclr/pal/src/misc/utils.cpp | 16 +++++----- src/coreclr/pal/src/thread/thread.cpp | 6 ++-- src/coreclr/scripts/genLttngProvider.py | 6 ++-- src/coreclr/utilcode/sstring.cpp | 7 +++-- src/coreclr/utilcode/util.cpp | 31 ++++++++++++------- src/coreclr/vm/assemblyspec.cpp | 7 +++-- src/coreclr/vm/eventtracepriv.h | 8 ++--- src/coreclr/vm/gcenv.ee.cpp | 2 +- src/coreclr/vm/interoputil.cpp | 8 ++--- src/coreclr/vm/object.cpp | 24 ++++++++------ 27 files changed, 157 insertions(+), 126 deletions(-) diff --git a/src/coreclr/debug/daccess/daccess.cpp b/src/coreclr/debug/daccess/daccess.cpp index c3299d7fdd84ef..697e5df4f8eae6 100644 --- a/src/coreclr/debug/daccess/daccess.cpp +++ b/src/coreclr/debug/daccess/daccess.cpp @@ -99,7 +99,8 @@ ConvertUtf8(_In_ LPCUTF8 utf8, if (nameLen) { - *nameLen = (ULONG32)minipal_get_length_utf8_to_utf16(utf8, cchUtf8, 0); + size_t cchName = minipal_get_length_utf8_to_utf16(utf8, cchUtf8, 0); + *nameLen = (ULONG32)cchName; } if (buffer && bufLen) @@ -124,15 +125,17 @@ AllocUtf8(_In_opt_ LPCWSTR wstr, } size_t cchSrc = srcChars == (ULONG32)-1 ? u16_strlen(wstr) + 1 : srcChars; - ULONG32 chars = (ULONG32)minipal_get_length_utf16_to_utf8((const CHAR16_T*)wstr, cchSrc, 0); + size_t chars = minipal_get_length_utf16_to_utf8((const CHAR16_T*)wstr, cchSrc, 0); // Make sure the converted string is always terminated. if (srcChars != (ULONG32)-1) { - if (!ClrSafeInt::addition(chars, 1, chars)) + S_SIZE_T charsWithNull = S_SIZE_T(chars) + S_SIZE_T(1); + if (charsWithNull.IsOverflow()) { return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); } + chars = charsWithNull.Value(); } char* mem = new (nothrow) char[chars]; diff --git a/src/coreclr/ilasm/assem.cpp b/src/coreclr/ilasm/assem.cpp index 63cc4a68a0fc16..b178543e48e370 100644 --- a/src/coreclr/ilasm/assem.cpp +++ b/src/coreclr/ilasm/assem.cpp @@ -1363,7 +1363,7 @@ char* Assembler::ReflectionNotation(mdToken tk) mdToken tkResScope; if(SUCCEEDED(m_pImporter->GetTypeRefProps(tk,&tkResScope,wzUniBuf,cchUniBuf,&N))) { - int ret = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)wzUniBuf,u16_strlen(wzUniBuf)+1,sz,szSizeBytes,0); + size_t ret = minipal_convert_utf16_to_utf8((const CHAR16_T*)wzUniBuf,u16_strlen(wzUniBuf)+1,sz,szSizeBytes,0); if(TypeFromToken(tkResScope)==mdtAssemblyRef) { AsmManAssembly *pAsmRef = m_pManifest->m_AsmRefLst.PEEK(RidFromToken(tkResScope)-1); @@ -1402,8 +1402,8 @@ char* Assembler::ReflectionNotation(mdToken tk) { memcpy(wzUniBuf,pAsmRef->pLocale->ptr(),L); wzUniBuf[L>>1] = 0; - ret = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)wzUniBuf,u16_strlen(wzUniBuf)+1,pc,szRemainingSizeBytes,0); - if (ret <= 0) + ret = minipal_convert_utf16_to_utf8((const CHAR16_T*)wzUniBuf,u16_strlen(wzUniBuf)+1,pc,szRemainingSizeBytes,0); + if (ret == 0) { report->error("Locale too long.\n"); *sz=0; @@ -1412,7 +1412,7 @@ char* Assembler::ReflectionNotation(mdToken tk) else { pc += ret; - szRemainingSizeBytes -= (size_t)ret; + szRemainingSizeBytes -= ret; } } } diff --git a/src/coreclr/ilasm/assembler.cpp b/src/coreclr/ilasm/assembler.cpp index 3a47286d42dd5c..3c45d0fc655ff8 100644 --- a/src/coreclr/ilasm/assembler.cpp +++ b/src/coreclr/ilasm/assembler.cpp @@ -1998,7 +1998,8 @@ void Assembler::SetPropMethod(int MethodCode, mdToken tk) /**************************************************************************/ void Assembler::EmitInstrStringLiteral(Instr* instr, BinStr* literal, BOOL ConvertToUnicode, BOOL Swap /*=FALSE*/) { - DWORD DataLen = literal->length(),L; + DWORD DataLen = literal->length(); + size_t L; uint8_t *pb = literal->ptr(); HRESULT hr = S_OK; mdToken tk; @@ -2014,7 +2015,7 @@ void Assembler::EmitInstrStringLiteral(Instr* instr, BinStr* literal, BOOL Conve literal->appendInt8(0); pb = literal->ptr(); // convert string to Unicode - L = UnicodeString ? (DWORD)minipal_convert_utf8_to_utf16((char*)pb,strlen((char*)pb)+1,(CHAR16_T*)UnicodeString,DataLen+1,0) : 0; + L = UnicodeString ? minipal_convert_utf8_to_utf16((char*)pb,strlen((char*)pb)+1,(CHAR16_T*)UnicodeString,DataLen+1,0) : 0; if(L == 0) { const char* sz=NULL; @@ -2051,7 +2052,7 @@ void Assembler::EmitInstrStringLiteral(Instr* instr, BinStr* literal, BOOL Conve // Add the string data to the metadata, which will fold dupes. hr = m_pEmitter->DefineUserString( UnicodeString, - L, + (ULONG)L, &tk ); if (FAILED(hr)) diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 461b6dccbd5463..0e18085443da2b 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -1717,21 +1717,20 @@ bool Compiler::fgVNBasedIntrinsicExpansionForCall_ReadUtf8(BasicBlock** pBlock, const int MaxU8BufferSizeInBytes = 256; uint8_t bufferU8[MaxU8BufferSizeInBytes]; - const int srcLenU8 = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)bufferU16, srcLenCnsU16, (char*)bufferU8, - MaxU8BufferSizeInBytes, 0); - if (srcLenU8 <= 0) + const size_t convertedLen = minipal_convert_utf16_to_utf8((const CHAR16_T*)bufferU16, srcLenCnsU16, (char*)bufferU8, + MaxU8BufferSizeInBytes, 0); + if (convertedLen == 0 || convertedLen > (size_t)MaxU8BufferSizeInBytes) { // E.g. output buffer is too small - JITDUMP("ReadUtf8: minipal_convert_utf16_to_utf8 returned <= 0\n") + JITDUMP("ReadUtf8: minipal_convert_utf16_to_utf8 returned 0 or too large\n") return false; } - // The API is expected to return [1..MaxU8BufferSizeInBytes] real length of the UTF-8 value - // stored in bufferU8 - assert((unsigned)srcLenU8 <= MaxU8BufferSizeInBytes); + // Bounded by MaxU8BufferSizeInBytes above; narrow for the unsigned JIT helpers below. + const unsigned srcLenU8 = (unsigned)convertedLen; // Now that we know the exact UTF8 buffer length we can check if it's unrollable - if (srcLenU8 > (int)getUnrollThreshold(UnrollKind::Memcpy)) + if (srcLenU8 > getUnrollThreshold(UnrollKind::Memcpy)) { JITDUMP("ReadUtf8: srcLenU8 is out of unrollable range\n") return false; diff --git a/src/coreclr/md/compiler/custattr_import.cpp b/src/coreclr/md/compiler/custattr_import.cpp index edd10f067c2056..81ab95b96ae107 100644 --- a/src/coreclr/md/compiler/custattr_import.cpp +++ b/src/coreclr/md/compiler/custattr_import.cpp @@ -35,14 +35,14 @@ STDMETHODIMP RegMeta::GetCustomAttributeByName( // S_OK or error. LPUTF8 szName; // Name in UFT8. size_t cchName; // Length of the name, including the terminator. - int iLen; // A length. + size_t iLen; // A length. CMiniMdRW *pMiniMd = NULL; LOCKREAD(); pMiniMd = &(m_pStgdb->m_MiniMd); cchName = u16_strlen(wzName) + 1; - iLen = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)wzName, cchName, 0); + iLen = minipal_get_length_utf16_to_utf8((const CHAR16_T*)wzName, cchName, 0); szName = (LPUTF8)_alloca(iLen); VERIFY(minipal_convert_utf16_to_utf8((const CHAR16_T*)wzName, cchName, szName, iLen, 0)); diff --git a/src/coreclr/md/compiler/import.cpp b/src/coreclr/md/compiler/import.cpp index acdee08ea8f1c6..6e8fff28ac22c9 100644 --- a/src/coreclr/md/compiler/import.cpp +++ b/src/coreclr/md/compiler/import.cpp @@ -2978,7 +2978,7 @@ HRESULT RegMeta::GetVersionString( // S_OK or error. REGMETA_POSSIBLE_INTERNAL_POINTER_EXPOSED(); - DWORD cch; // Length of WideChar string. + size_t cch; // Length of WideChar string. LPCSTR pVer; // Pointer to version string. LOCKREAD(); @@ -2991,16 +2991,16 @@ HRESULT RegMeta::GetVersionString( // S_OK or error. size_t cchVer = strlen(pVer) + 1; if (cchBufSize == 0) { // Only the space required. - cch = (DWORD)minipal_get_length_utf8_to_utf16(pVer, cchVer, 0); + cch = minipal_get_length_utf8_to_utf16(pVer, cchVer, 0); } else { // Attempt to convert into caller's buffer. - cch = (DWORD)minipal_convert_utf8_to_utf16(pVer, cchVer, (CHAR16_T*)pwzBuf, cchBufSize, 0); + cch = minipal_convert_utf8_to_utf16(pVer, cchVer, (CHAR16_T*)pwzBuf, cchBufSize, 0); // Did the string fit? if (cch == 0) { // No, didn't fit. Find out space required. - cch = (DWORD)minipal_get_length_utf8_to_utf16(pVer, cchVer, 0); + cch = minipal_get_length_utf8_to_utf16(pVer, cchVer, 0); // NUL terminate string. pwzBuf[cchBufSize-1] = W('\0'); // Truncation return code. @@ -3016,7 +3016,7 @@ HRESULT RegMeta::GetVersionString( // S_OK or error. } if (pchBufSize) - *pchBufSize = cch; + *pchBufSize = (DWORD)cch; ErrExit: return hr; diff --git a/src/coreclr/md/enc/metamodelrw.cpp b/src/coreclr/md/enc/metamodelrw.cpp index 884c9e0a57a7b5..713e4c5a58c126 100644 --- a/src/coreclr/md/enc/metamodelrw.cpp +++ b/src/coreclr/md/enc/metamodelrw.cpp @@ -3820,7 +3820,7 @@ CMiniMdRW::Impl_GetStringW( { LPCSTR szString; // Single byte version. size_t cchString; // Length of the single byte version, including the terminator. - int iSize; // Size of resulting string, in wide chars. + size_t iSize; // Size of resulting string, in wide chars. HRESULT hr = NOERROR; IfFailGo(getString(ix, &szString)); @@ -3836,14 +3836,17 @@ CMiniMdRW::Impl_GetStringW( } cchString = strlen(szString) + 1; if (cchBuffer == 0) - iSize = (int)minipal_get_length_utf8_to_utf16(szString, cchString, 0); + iSize = minipal_get_length_utf8_to_utf16(szString, cchString, 0); else - iSize = szOut != NULL ? (int)minipal_convert_utf8_to_utf16(szString, cchString, (CHAR16_T*)szOut, cchBuffer, 0) : 0; + iSize = szOut != NULL ? minipal_convert_utf8_to_utf16(szString, cchString, (CHAR16_T*)szOut, cchBuffer, 0) : 0; if (iSize == 0) { // Truncation error; get the size required. if (pcchBuffer) - *pcchBuffer = (ULONG)minipal_get_length_utf8_to_utf16(szString, cchString, 0); + { + size_t cchNeeded = minipal_get_length_utf8_to_utf16(szString, cchString, 0); + *pcchBuffer = (ULONG)cchNeeded; + } if ((szOut != NULL) && (cchBuffer > 0)) { // null-terminate the truncated output string @@ -3854,7 +3857,7 @@ CMiniMdRW::Impl_GetStringW( goto ErrExit; } if (pcchBuffer) - *pcchBuffer = iSize; + *pcchBuffer = (ULONG)iSize; ErrExit: return hr; diff --git a/src/coreclr/md/enc/stgtiggerstorage.cpp b/src/coreclr/md/enc/stgtiggerstorage.cpp index 8774d055530845..1f89a48bb44891 100644 --- a/src/coreclr/md/enc/stgtiggerstorage.cpp +++ b/src/coreclr/md/enc/stgtiggerstorage.cpp @@ -358,11 +358,13 @@ TiggerStorage::GetStreamSaveSize( UINT32 cbDataSize, // Size of data to go into stream. UINT32 *pcbSaveSize) // Return data size plus stream overhead. { + size_t cbName; // Converted stream name length. UINT32 cbTotalSize; // Add up each element. // Find out how large the name will be. - cbTotalSize = (UINT32)minipal_get_length_utf16_to_utf8((const CHAR16_T*)szStreamName, u16_strlen(szStreamName) + 1, 0); - _ASSERTE(cbTotalSize != 0); + cbName = minipal_get_length_utf16_to_utf8((const CHAR16_T*)szStreamName, u16_strlen(szStreamName) + 1, 0); + _ASSERTE(cbName != 0); + cbTotalSize = (UINT32)cbName; // Add the size of the stream header minus the static name array. cbTotalSize += sizeof(STORAGESTREAM) - MAXSTREAMNAME; diff --git a/src/coreclr/md/runtime/metamodelro.cpp b/src/coreclr/md/runtime/metamodelro.cpp index 202001284a5c4d..ca327f28a49b4a 100644 --- a/src/coreclr/md/runtime/metamodelro.cpp +++ b/src/coreclr/md/runtime/metamodelro.cpp @@ -103,7 +103,7 @@ CMiniMd::Impl_GetStringW( { LPCSTR szString; // Single byte version. size_t cchString; // Length of the single byte version, including the terminator. - int iSize; // Size of resulting string, in wide chars. + size_t iSize; // Size of resulting string, in wide chars. HRESULT hr = NOERROR; IfFailGo(getString(ix, &szString)); @@ -119,14 +119,17 @@ CMiniMd::Impl_GetStringW( } cchString = strlen(szString) + 1; if (cchBuffer == 0) - iSize = (int)minipal_get_length_utf8_to_utf16(szString, cchString, 0); + iSize = minipal_get_length_utf8_to_utf16(szString, cchString, 0); else - iSize = szOut != NULL ? (int)minipal_convert_utf8_to_utf16(szString, cchString, (CHAR16_T*)szOut, cchBuffer, 0) : 0; + iSize = szOut != NULL ? minipal_convert_utf8_to_utf16(szString, cchString, (CHAR16_T*)szOut, cchBuffer, 0) : 0; if (iSize == 0) { // Truncation error; get the size required. if (pcchBuffer != NULL) - *pcchBuffer = (ULONG)minipal_get_length_utf8_to_utf16(szString, cchString, 0); + { + size_t cchNeeded = minipal_get_length_utf8_to_utf16(szString, cchString, 0); + *pcchBuffer = (ULONG)cchNeeded; + } if ((szOut != NULL) && (cchBuffer > 0)) { // null-terminate the truncated output string @@ -137,7 +140,7 @@ CMiniMd::Impl_GetStringW( goto ErrExit; } if (pcchBuffer != NULL) - *pcchBuffer = iSize; + *pcchBuffer = (ULONG)iSize; ErrExit: return hr; diff --git a/src/coreclr/md/runtime/stgpool.cpp b/src/coreclr/md/runtime/stgpool.cpp index 4a12348e670ba7..04395f867cad71 100644 --- a/src/coreclr/md/runtime/stgpool.cpp +++ b/src/coreclr/md/runtime/stgpool.cpp @@ -970,7 +970,7 @@ StgStringPool::AddStringW( CONTRACTL_END STRINGHASH *pHash; // Hash item for add. - ULONG iLen; // Correct length after conversion. + size_t iLen; // Correct length after conversion. LPSTR pData; // Pointer to location for new string. _ASSERTE(!m_bReadOnly); @@ -988,18 +988,18 @@ StgStringPool::AddStringW( // How many bytes will be required in the heap, including the trailing 0? size_t cchString = u16_strlen(szString) + 1; - iLen = (ULONG)minipal_get_length_utf16_to_utf8((const CHAR16_T*)szString, cchString, 0); + iLen = minipal_get_length_utf16_to_utf8((const CHAR16_T*)szString, cchString, 0); // Check for room. if (iLen > GetCbSegAvailable()) { - if (!Grow(iLen)) + if (!Grow((ULONG)iLen)) return (PostError(OutOfMemory())); } pData = reinterpret_cast(GetNextLocation()); // Convert the data in place to the correct location. - iLen = (ULONG)minipal_convert_utf16_to_utf8((const CHAR16_T*)szString, cchString, pData, GetCbSegAvailable(), 0); + iLen = minipal_convert_utf16_to_utf8((const CHAR16_T*)szString, cchString, pData, GetCbSegAvailable(), 0); if (iLen == 0) return (BadError(HRESULT_FROM_NT(errno))); @@ -1015,7 +1015,7 @@ StgStringPool::AddStringW( if (pHash->iOffset == 0xffffffff) { *pnOffset = pHash->iOffset = GetNextOffset(); - SegAllocate(iLen); + SegAllocate((ULONG)iLen); } // Else use the old one. else @@ -1027,7 +1027,7 @@ StgStringPool::AddStringW( else { *pnOffset = GetNextOffset(); - SegAllocate(iLen); + SegAllocate((ULONG)iLen); } return (S_OK); } // StgStringPool::AddStringW diff --git a/src/coreclr/nativeresources/resourcestring.cpp b/src/coreclr/nativeresources/resourcestring.cpp index 23903f52981217..53c5488c8c8cdf 100644 --- a/src/coreclr/nativeresources/resourcestring.cpp +++ b/src/coreclr/nativeresources/resourcestring.cpp @@ -22,7 +22,7 @@ static int CompareNativeStringResources(const void *a, const void *b) int LoadNativeStringResource(const NativeStringResourceTable &nativeStringResourceTable, unsigned int iResourceID, WCHAR* szBuffer, int iMax, int *pcwchUsed) { - int len = 0; + size_t len = 0; if (szBuffer && iMax) { // Search the sorted set of resources for the ID we're interested in. @@ -37,7 +37,7 @@ int LoadNativeStringResource(const NativeStringResourceTable &nativeStringResour if (resourceEntry != NULL) { const char* resourceString = resourceEntry->resourceString; - len = (int)minipal_convert_utf8_to_utf16(resourceString, strlen(resourceString) + 1, (CHAR16_T*)szBuffer, iMax, 0); + len = minipal_convert_utf8_to_utf16(resourceString, strlen(resourceString) + 1, (CHAR16_T*)szBuffer, iMax, 0); if (len == 0) { // Tell the caller if the buffer isn't big enough @@ -63,7 +63,7 @@ int LoadNativeStringResource(const NativeStringResourceTable &nativeStringResour if (nxt != NULL) { - len = (int)(nxt - szBuffer); + len = (size_t)(nxt - szBuffer); } else { @@ -78,7 +78,7 @@ int LoadNativeStringResource(const NativeStringResourceTable &nativeStringResour if (pcwchUsed) { - *pcwchUsed = len; + *pcwchUsed = (int)len; } return S_OK; diff --git a/src/coreclr/pal/src/cruntime/wchar.cpp b/src/coreclr/pal/src/cruntime/wchar.cpp index 7c889685d33b3e..7ddcce37ad3e3a 100644 --- a/src/coreclr/pal/src/cruntime/wchar.cpp +++ b/src/coreclr/pal/src/cruntime/wchar.cpp @@ -37,14 +37,14 @@ __cdecl _wtoi( const wchar_16 *string) { - int len; + size_t len; int ret; char *tempStr; PERF_ENTRY(_wtoi); ENTRY("_wtoi (string=%p)\n", string); - len = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)string, PAL_wcslen(string) + 1, 0); + len = minipal_get_length_utf16_to_utf8((const CHAR16_T*)string, PAL_wcslen(string) + 1, 0); if (!len) { ASSERT("UTF-16 to UTF-8 conversion failed. Error is %d\n", @@ -58,7 +58,7 @@ _wtoi( SetLastError(ERROR_NOT_ENOUGH_MEMORY); return -1; } - len = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)string, PAL_wcslen(string) + 1, tempStr, len, 0); + len = minipal_convert_utf16_to_utf8((const CHAR16_T*)string, PAL_wcslen(string) + 1, tempStr, len, 0); if (!len) { ASSERT("UTF-16 to UTF-8 conversion failed. Error is %d\n", @@ -241,14 +241,14 @@ PAL_wcstoul( char *s_nptr = 0; char *s_endptr = 0; unsigned long res; - int size; + size_t size; DWORD dwLastError = 0; PERF_ENTRY(wcstoul); ENTRY("wcstoul (nptr=%p (%S), endptr=%p, base=%d)\n", nptr?nptr:W16_NULLSTRING, nptr?nptr:W16_NULLSTRING, endptr, base); - size = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, 0); + size = minipal_get_length_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, 0); if (!size) { dwLastError = GetLastError(); @@ -265,7 +265,7 @@ PAL_wcstoul( res = 0; goto PAL_wcstoulExit; } - size = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, s_nptr, size, 0); + size = minipal_convert_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, s_nptr, size, 0); if (!size) { dwLastError = GetLastError(); @@ -331,14 +331,14 @@ PAL__wcstoui64( char *s_nptr = 0; char *s_endptr = 0; unsigned long long res; - int size; + size_t size; DWORD dwLastError = 0; PERF_ENTRY(wcstoul); ENTRY("_wcstoui64 (nptr=%p (%S), endptr=%p, base=%d)\n", nptr?nptr:W16_NULLSTRING, nptr?nptr:W16_NULLSTRING, endptr, base); - size = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, 0); + size = minipal_get_length_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, 0); if (!size) { dwLastError = GetLastError(); @@ -355,7 +355,7 @@ PAL__wcstoui64( res = 0; goto PAL__wcstoui64Exit; } - size = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, s_nptr, size, 0); + size = minipal_convert_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, s_nptr, size, 0); if (!size) { dwLastError = GetLastError(); diff --git a/src/coreclr/pal/src/debug/debug.cpp b/src/coreclr/pal/src/debug/debug.cpp index 68a28371fd60a5..0a7097bbccdcf6 100644 --- a/src/coreclr/pal/src/debug/debug.cpp +++ b/src/coreclr/pal/src/debug/debug.cpp @@ -171,7 +171,7 @@ OutputDebugStringW( IN LPCWSTR lpOutputString) { CHAR *lpOutputStringA; - int strLen; + size_t strLen; PERF_ENTRY(OutputDebugStringW); ENTRY("OutputDebugStringW (lpOutputString=%p (%S))\n", @@ -184,7 +184,7 @@ OutputDebugStringW( goto EXIT; } - if ((strLen = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpOutputString, PAL_wcslen(lpOutputString) + 1, 0)) + if ((strLen = minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpOutputString, PAL_wcslen(lpOutputString) + 1, 0)) == 0) { ASSERT("failed to get wide chars length\n"); diff --git a/src/coreclr/pal/src/init/pal.cpp b/src/coreclr/pal/src/init/pal.cpp index e965ff987ddab9..0fb193f9da1175 100644 --- a/src/coreclr/pal/src/init/pal.cpp +++ b/src/coreclr/pal/src/init/pal.cpp @@ -692,7 +692,7 @@ BOOL PALInitLock(void) static LPWSTR INIT_GetCurrentEXEPath() { LPWSTR return_value; - INT return_size; + size_t return_size; char* path = minipal_getexepath(); if (!path) @@ -705,7 +705,7 @@ static LPWSTR INIT_GetCurrentEXEPath() real_path.Set(path, strlen(path)); free(path); - return_size = (INT)minipal_get_length_utf8_to_utf16(real_path, strlen(real_path) + 1, 0); + return_size = minipal_get_length_utf8_to_utf16(real_path, strlen(real_path) + 1, 0); if (0 == return_size) { ASSERT("UTF-8 to UTF-16 conversion failure\n"); diff --git a/src/coreclr/pal/src/loader/module.cpp b/src/coreclr/pal/src/loader/module.cpp index de948ddd5221b7..d0159ffad21a48 100644 --- a/src/coreclr/pal/src/loader/module.cpp +++ b/src/coreclr/pal/src/loader/module.cpp @@ -382,6 +382,7 @@ GetModuleFileNameA( INT name_length; DWORD retval = 0; LPWSTR wide_name = nullptr; + size_t converted = 0; PERF_ENTRY(GetModuleFileNameA); ENTRY("GetModuleFileNameA (hModule=%p, lpFileName=%p, nSize=%u)\n", @@ -405,8 +406,8 @@ GetModuleFileNameA( /* Convert module name to Ascii, place it in the supplied buffer */ - name_length = (INT)minipal_convert_utf16_to_utf8((const CHAR16_T*)wide_name, PAL_wcslen(wide_name) + 1, lpFileName, nSize, 0); - if (name_length == 0) + converted = minipal_convert_utf16_to_utf8((const CHAR16_T*)wide_name, PAL_wcslen(wide_name) + 1, lpFileName, nSize, 0); + if (converted == 0) { TRACE("Buffer too small to copy module's file name.\n"); SetLastError(ERROR_INSUFFICIENT_BUFFER); @@ -414,6 +415,7 @@ GetModuleFileNameA( } TRACE("File name of module %p is %s\n", hModule, lpFileName); + name_length = (INT)converted; retval = name_length; done: UnlockModuleList(); @@ -1293,7 +1295,8 @@ static bool LOADConvertLibraryPathWideStringToMultibyteString( _ASSERTE(wideLibraryPath != nullptr); size_t length = (PAL_wcslen(wideLibraryPath)+1) * MaxWCharToAcpLengthFactor; - *multibyteLibraryPathLengthRef = (INT)minipal_convert_utf16_to_utf8((const CHAR16_T*)wideLibraryPath, PAL_wcslen(wideLibraryPath) + 1, multibyteLibraryPath, length, 0); + size_t converted = minipal_convert_utf16_to_utf8((const CHAR16_T*)wideLibraryPath, PAL_wcslen(wideLibraryPath) + 1, multibyteLibraryPath, length, 0); + *multibyteLibraryPathLengthRef = (INT)converted; if (*multibyteLibraryPathLengthRef == 0) { diff --git a/src/coreclr/pal/src/misc/environ.cpp b/src/coreclr/pal/src/misc/environ.cpp index 957d56c8f5f204..a42ccb1c8c0396 100644 --- a/src/coreclr/pal/src/misc/environ.cpp +++ b/src/coreclr/pal/src/misc/environ.cpp @@ -155,7 +155,7 @@ GetEnvironmentVariableW( { CHAR *inBuff = nullptr; CHAR *outBuff = nullptr; - INT inBuffSize; + size_t inBuffSize; DWORD size = 0; PERF_ENTRY(GetEnvironmentVariableW); @@ -163,7 +163,7 @@ GetEnvironmentVariableW( lpName ? lpName : W16_NULLSTRING, lpName ? lpName : W16_NULLSTRING, lpBuffer, nSize); - inBuffSize = lpName != nullptr ? (INT)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpName, PAL_wcslen(lpName) + 1, 0) : 0; + inBuffSize = lpName != nullptr ? minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpName, PAL_wcslen(lpName) + 1, 0) : 0; if (0 == inBuffSize) { ERROR("lpName has to be a valid parameter\n"); @@ -214,7 +214,8 @@ GetEnvironmentVariableW( } else { - size = (DWORD)minipal_convert_utf8_to_utf16(outBuff, strlen(outBuff) + 1, (CHAR16_T*)lpBuffer, nSize, 0); + size_t converted = minipal_convert_utf8_to_utf16(outBuff, strlen(outBuff) + 1, (CHAR16_T*)lpBuffer, nSize, 0); + size = (DWORD)converted; if (0 != size) { // -1 for the null. @@ -280,8 +281,8 @@ SetEnvironmentVariableW( { PCHAR name = nullptr; PCHAR value = nullptr; - INT nameSize = 0; - INT valueSize = 0; + size_t nameSize = 0; + size_t valueSize = 0; BOOL bRet = FALSE; PERF_ENTRY(SetEnvironmentVariableW); @@ -289,7 +290,7 @@ SetEnvironmentVariableW( lpName?lpName:W16_NULLSTRING, lpName?lpName:W16_NULLSTRING, lpValue?lpValue:W16_NULLSTRING, lpValue?lpValue:W16_NULLSTRING); - if ((nameSize = lpName != nullptr ? (INT)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpName, PAL_wcslen(lpName) + 1, 0) : 0) == 0) + if ((nameSize = lpName != nullptr ? minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpName, PAL_wcslen(lpName) + 1, 0) : 0) == 0) { ERROR("UTF-16 to UTF-8 conversion failed\n"); SetLastError(ERROR_INVALID_PARAMETER); @@ -313,7 +314,7 @@ SetEnvironmentVariableW( if (lpValue != nullptr) { - if ((valueSize = (INT)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpValue, PAL_wcslen(lpValue) + 1, 0)) == 0) + if ((valueSize = minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpValue, PAL_wcslen(lpValue) + 1, 0)) == 0) { ERROR("UTF-16 to UTF-8 conversion failed\n"); SetLastError(ERROR_INVALID_PARAMETER); @@ -379,7 +380,8 @@ GetEnvironmentStringsW( VOID) { WCHAR *wenviron = nullptr, *tempEnviron; - int i, len, envNum; + int i; + size_t len, envNum; PERF_ENTRY(GetEnvironmentStringsW); ENTRY("GetEnvironmentStringsW()\n"); @@ -393,7 +395,7 @@ GetEnvironmentStringsW( /* get total length of the bytes that we need to allocate */ for (i = 0; palEnvironment[i] != 0; i++) { - len = (int)minipal_get_length_utf8_to_utf16(palEnvironment[i], strlen(palEnvironment[i]) + 1, 0); + len = minipal_get_length_utf8_to_utf16(palEnvironment[i], strlen(palEnvironment[i]) + 1, 0); envNum += len; } @@ -409,7 +411,7 @@ GetEnvironmentStringsW( tempEnviron = wenviron; for (i = 0; palEnvironment[i] != 0; i++) { - len = (int)minipal_convert_utf8_to_utf16(palEnvironment[i], strlen(palEnvironment[i]) + 1, (CHAR16_T*)tempEnviron, envNum, 0); + len = minipal_convert_utf8_to_utf16(palEnvironment[i], strlen(palEnvironment[i]) + 1, (CHAR16_T*)tempEnviron, envNum, 0); tempEnviron += len; envNum -= len; } diff --git a/src/coreclr/pal/src/misc/fmtmessage.cpp b/src/coreclr/pal/src/misc/fmtmessage.cpp index 1e8d6cf48a3223..c578639080aa7e 100644 --- a/src/coreclr/pal/src/misc/fmtmessage.cpp +++ b/src/coreclr/pal/src/misc/fmtmessage.cpp @@ -105,11 +105,9 @@ static INT FMTMSG__watoi( LPWSTR str ) { CONST UINT MAX_NUMBER_LENGTH = 3; CHAR buf[ MAX_NUMBER_LENGTH ]; - INT nRetVal = 0; + size_t converted = minipal_convert_utf16_to_utf8((const CHAR16_T*)str, PAL_wcslen(str) + 1, buf, MAX_NUMBER_LENGTH, 0); - nRetVal = (INT)minipal_convert_utf16_to_utf8((const CHAR16_T*)str, PAL_wcslen(str) + 1, buf, MAX_NUMBER_LENGTH, 0); - - if ( nRetVal != 0 ) + if ( converted != 0 ) { return atoi( buf ); } diff --git a/src/coreclr/pal/src/misc/utils.cpp b/src/coreclr/pal/src/misc/utils.cpp index a0c10cc26e731c..5bd995307518e8 100644 --- a/src/coreclr/pal/src/misc/utils.cpp +++ b/src/coreclr/pal/src/misc/utils.cpp @@ -54,11 +54,11 @@ Return Value : LPSTR UTIL_WCToMB_Alloc(LPCWSTR lpWideCharStr, int cchWideChar) { size_t cchSource = cchWideChar < 0 ? PAL_wcslen(lpWideCharStr) + 1 : (size_t)cchWideChar; - int length; + size_t length; LPSTR lpMultiByteStr; /* get required buffer length */ - length = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpWideCharStr, cchSource, 0); + length = minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpWideCharStr, cchSource, 0); if(0 == length) { ERROR("WCToMB error; GetLastError returns %#x", GetLastError()); @@ -75,7 +75,7 @@ LPSTR UTIL_WCToMB_Alloc(LPCWSTR lpWideCharStr, int cchWideChar) } /* convert into allocated buffer */ - length = (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)lpWideCharStr, cchSource, lpMultiByteStr, length, 0); + length = minipal_convert_utf16_to_utf8((const CHAR16_T*)lpWideCharStr, cchSource, lpMultiByteStr, length, 0); if(0 == length) { ASSERT("WCToMB error; GetLastError returns %#x\n", GetLastError()); @@ -105,11 +105,11 @@ Return Value : LPWSTR UTIL_MBToWC_Alloc(LPCSTR lpMultiByteStr, int cbMultiByte) { size_t cbSource = cbMultiByte < 0 ? strlen(lpMultiByteStr) + 1 : (size_t)cbMultiByte; - int length; + size_t length; LPWSTR lpWideCharStr; /* get required buffer length */ - length = (int)minipal_get_length_utf8_to_utf16(lpMultiByteStr, cbSource, 0); + length = minipal_get_length_utf8_to_utf16(lpMultiByteStr, cbSource, 0); if(0 == length) { ERROR("MBToWC error; GetLastError returns %#x", GetLastError()); @@ -120,7 +120,7 @@ LPWSTR UTIL_MBToWC_Alloc(LPCSTR lpMultiByteStr, int cbMultiByte) size_t fullsize; if (!ClrSafeInt::multiply(length,sizeof(WCHAR),fullsize)) { - ERROR("integer overflow! length = %d , sizeof(WCHAR) = (%d)\n", length,sizeof(WCHAR) ); + ERROR("integer overflow! length = %zu , sizeof(WCHAR) = (%zu)\n", length,sizeof(WCHAR) ); SetLastError(ERROR_ARITHMETIC_OVERFLOW); return NULL; } @@ -134,8 +134,8 @@ LPWSTR UTIL_MBToWC_Alloc(LPCSTR lpMultiByteStr, int cbMultiByte) } /* convert into allocated buffer */ - length = (int)minipal_convert_utf8_to_utf16(lpMultiByteStr, cbSource, (CHAR16_T*)lpWideCharStr, length, 0); - if(0 >= length) + length = minipal_convert_utf8_to_utf16(lpMultiByteStr, cbSource, (CHAR16_T*)lpWideCharStr, length, 0); + if(0 == length) { ASSERT("MCToMB error; GetLastError returns %#x\n", GetLastError()); free(lpWideCharStr); diff --git a/src/coreclr/pal/src/thread/thread.cpp b/src/coreclr/pal/src/thread/thread.cpp index 5eb7fa9f4f6ecb..f5d80cbf0063c4 100644 --- a/src/coreclr/pal/src/thread/thread.cpp +++ b/src/coreclr/pal/src/thread/thread.cpp @@ -1303,7 +1303,7 @@ SetThreadDescription( CPalThread *pTargetThread = NULL; IPalObject *pobjThread = NULL; - int nameSize; + size_t nameSize; char *nameBuf = NULL; PAL_ERROR palError = InternalGetThreadDataFromHandle(pThread, hThread, &pTargetThread, &pobjThread); @@ -1313,11 +1313,11 @@ SetThreadDescription( // it causes the value returned by Process.ProcessName to change. if ((pid_t)pTargetThread->GetThreadId() != getpid()) { - nameSize = lpThreadDescription != NULL ? (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpThreadDescription, PAL_wcslen(lpThreadDescription) + 1, 0) : 0; + nameSize = lpThreadDescription != NULL ? minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpThreadDescription, PAL_wcslen(lpThreadDescription) + 1, 0) : 0; if (nameSize > 0) { nameBuf = (char *)malloc(nameSize); - if (nameBuf == NULL || (int)minipal_convert_utf16_to_utf8((const CHAR16_T*)lpThreadDescription, PAL_wcslen(lpThreadDescription) + 1, nameBuf, nameSize, 0) != nameSize) + if (nameBuf == NULL || minipal_convert_utf16_to_utf8((const CHAR16_T*)lpThreadDescription, PAL_wcslen(lpThreadDescription) + 1, nameBuf, nameSize, 0) != nameSize) { pThread->SetLastError(ERROR_INSUFFICIENT_BUFFER); } diff --git a/src/coreclr/scripts/genLttngProvider.py b/src/coreclr/scripts/genLttngProvider.py index c782d9be97f18f..11e8ac976713a6 100644 --- a/src/coreclr/scripts/genLttngProvider.py +++ b/src/coreclr/scripts/genLttngProvider.py @@ -312,9 +312,9 @@ def generateMethodBody(template, providerName, eventName, runtimeFlavor): paramname = fnparam.name if fnparam.winType == "win:UnicodeString": - result.append(" INT " + paramname + "_path_size = -1;\n") + result.append(" size_t " + paramname + "_path_size = 0;\n") result.append(" PathCharString " + paramname + "_PS;\n") - result.append(" INT " + paramname + "_full_name_path_size") + result.append(" size_t " + paramname + "_full_name_path_size") result.append(" = (lttng_strlen16(" + paramname + ") + 1)*sizeof(WCHAR);\n") result.append(" CHAR* " + paramname + "_full_name = ") result.append(paramname + "_PS.OpenStringBuffer(" + paramname + "_full_name_path_size );\n") @@ -343,7 +343,7 @@ def generateMethodBody(template, providerName, eventName, runtimeFlavor): if ctf_type == "ctf_string" and wintypeName == "win:UnicodeString": #emit code to convert unicode to ansi string - result.append(" " + paramname + "_path_size = (INT)minipal_convert_utf16_to_utf8((const CHAR16_T*)") + result.append(" " + paramname + "_path_size = minipal_convert_utf16_to_utf8((const CHAR16_T*)") result.append(paramname + ", lttng_strlen16(" + paramname + ") + 1, ") result.append(paramname + "_full_name, ") result.append(paramname + "_full_name_path_size, 0);\n") diff --git a/src/coreclr/utilcode/sstring.cpp b/src/coreclr/utilcode/sstring.cpp index 979de9bf891ea4..8329fbd6bb5964 100644 --- a/src/coreclr/utilcode/sstring.cpp +++ b/src/coreclr/utilcode/sstring.cpp @@ -774,9 +774,9 @@ void SString::ConvertToUnicode(SString &s) const UNREACHABLE(); } - COUNT_T length = (COUNT_T)minipal_get_length_utf8_to_utf16(GetRawUTF8(), GetRawCount() + 1, 0); + size_t length = minipal_get_length_utf8_to_utf16(GetRawUTF8(), GetRawCount() + 1, 0); - s.Resize(length - 1, REPRESENTATION_UNICODE); + s.Resize((COUNT_T)(length - 1), REPRESENTATION_UNICODE); if (minipal_convert_utf8_to_utf16(GetRawUTF8(), GetRawCount() + 1, (CHAR16_T*)s.GetRawUnicode(), length, 0) == 0) ThrowWin32(errno); @@ -2264,7 +2264,8 @@ bool SString::DacGetUnicode(COUNT_T cBufChars, size_t length = strlen(pString) + 1; if (pcNeedChars) { - *pcNeedChars = (COUNT_T)minipal_get_length_utf8_to_utf16(pString, length, 0); + size_t cchNeed = minipal_get_length_utf8_to_utf16(pString, length, 0); + *pcNeedChars = (COUNT_T)cchNeed; } if (pBuffer && cBufChars) { diff --git a/src/coreclr/utilcode/util.cpp b/src/coreclr/utilcode/util.cpp index edfe522e0261f7..58a21e1d497175 100644 --- a/src/coreclr/utilcode/util.cpp +++ b/src/coreclr/utilcode/util.cpp @@ -1620,9 +1620,9 @@ HRESULT Utf2Quick( CONTRACTL_END; HRESULT hr = S_OK; // A result. - int iReqLen; // Required additional length. - int iActLen; - int bAlloc = 0; // If non-zero, allocation was required. + size_t cchReq; // Required additional length. + size_t cchAct; + bool bAlloc = false; // If true, allocation was required. if (iCurLen < 0 ) { @@ -1632,7 +1632,7 @@ HRESULT Utf2Quick( // Calculate the space available S_SIZE_T cchAvail = S_SIZE_T(rStr.MaxSize()) - S_SIZE_T(iCurLen); - if (cchAvail.IsOverflow() || cchAvail.Value() > INT_MAX) + if (cchAvail.IsOverflow()) { _ASSERTE_MSG(false, "Integer overflow/underflow"); return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); @@ -1646,21 +1646,30 @@ HRESULT Utf2Quick( return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); } size_t cchSrc = strlen(pStr) + 1; - iReqLen = (int)minipal_convert_utf8_to_utf16(pStr, cchSrc, (CHAR16_T*)rNewStr, cchAvail.Value(), 0); + cchReq = minipal_convert_utf8_to_utf16(pStr, cchSrc, (CHAR16_T*)rNewStr, cchAvail.Value(), 0); // If the buffer was too small, determine what is required. - if (iReqLen == 0) - bAlloc = iReqLen = (int)minipal_get_length_utf8_to_utf16(pStr, cchSrc, 0); + if (cchReq == 0) + { + cchReq = minipal_get_length_utf8_to_utf16(pStr, cchSrc, 0); + bAlloc = true; + } // Resize the buffer. If the buffer was large enough, this just sets the internal // counter, but if it was too small, this will attempt a reallocation. Note that // the length includes the terminating W('/0'). - IfFailGo(rStr.ReSizeNoThrow(iCurLen+iReqLen)); + S_SIZE_T newSize = S_SIZE_T(iCurLen) + S_SIZE_T(cchReq); + if (newSize.IsOverflow()) + { + _ASSERTE_MSG(false, "Integer overflow/underflow"); + return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + } + IfFailGo(rStr.ReSizeNoThrow(newSize.Value())); // If we had to realloc, then do the conversion again, now that the buffer is // large enough. if (bAlloc) { //recalculating cchAvail since MaxSize could have been changed. cchAvail = S_SIZE_T(rStr.MaxSize()) - S_SIZE_T(iCurLen); - if (cchAvail.IsOverflow() || cchAvail.Value() > INT_MAX) + if (cchAvail.IsOverflow()) { _ASSERTE_MSG(false, "Integer overflow/underflow"); return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); @@ -1673,8 +1682,8 @@ HRESULT Utf2Quick( _ASSERTE_MSG(false, "Integer overflow/underflow"); return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); } - iActLen = (int)minipal_convert_utf8_to_utf16(pStr, cchSrc, (CHAR16_T*)rNewStr, cchAvail.Value(), 0); - _ASSERTE(iReqLen == iActLen); + cchAct = minipal_convert_utf8_to_utf16(pStr, cchSrc, (CHAR16_T*)rNewStr, cchAvail.Value(), 0); + _ASSERTE(cchReq == cchAct); } ErrExit: return hr; diff --git a/src/coreclr/vm/assemblyspec.cpp b/src/coreclr/vm/assemblyspec.cpp index a1c906ef84c29c..4c02d60c09dfc7 100644 --- a/src/coreclr/vm/assemblyspec.cpp +++ b/src/coreclr/vm/assemblyspec.cpp @@ -428,9 +428,10 @@ HRESULT AssemblySpec::EmitToken( if (m_context.szLocale) { size_t cchLocale = strlen(m_context.szLocale) + 1; - AMD.cbLocale = (ULONG)minipal_get_length_utf8_to_utf16(m_context.szLocale, cchLocale, 0); - AMD.szLocale = (LPWSTR) alloca(AMD.cbLocale * sizeof(WCHAR) ); - if(minipal_convert_utf8_to_utf16(m_context.szLocale, cchLocale, (CHAR16_T*)AMD.szLocale, AMD.cbLocale, 0)==0) + size_t cchWideLocale = minipal_get_length_utf8_to_utf16(m_context.szLocale, cchLocale, 0); + AMD.cbLocale = (ULONG)cchWideLocale; + AMD.szLocale = (LPWSTR) alloca(cchWideLocale * sizeof(WCHAR) ); + if(minipal_convert_utf8_to_utf16(m_context.szLocale, cchLocale, (CHAR16_T*)AMD.szLocale, cchWideLocale, 0)==0) IfFailGo(HRESULT_FROM_WIN32(errno)); } else { diff --git a/src/coreclr/vm/eventtracepriv.h b/src/coreclr/vm/eventtracepriv.h index 11927c08144657..ea5504c80cb67b 100644 --- a/src/coreclr/vm/eventtracepriv.h +++ b/src/coreclr/vm/eventtracepriv.h @@ -127,14 +127,14 @@ struct EventStaticEntry // The location in the structure to write to. We won't actually write here unless we have sufficient buffer. WCHAR *name = (WCHAR *)(ptr + offsetof(EventStaticEntry, Name)); - int len = 0; + size_t len = 0; LPCUTF8 utf8Name = 0; if (SUCCEEDED(fieldDesc->GetName_NoThrow(&utf8Name))) { - len = (int)minipal_convert_utf8_to_utf16(utf8Name, strlen(utf8Name) + 1, (CHAR16_T*)name, + len = minipal_convert_utf8_to_utf16(utf8Name, strlen(utf8Name) + 1, (CHAR16_T*)name, (sizeRemaining - sizeof(EventStaticEntry)) / sizeof(WCHAR), 0); - if (len <= 0) + if (len == 0) { // We will only emit names for fields which are up to 255 characters (and also don't fit in the buffer). if (sizeRemaining < MaxEntrySize()) @@ -163,7 +163,7 @@ struct EventStaticEntry entry->TypeID = typeId; entry->Flags = flags; - return sizeof(EventStaticEntry) + len * sizeof(WCHAR); + return (int)(sizeof(EventStaticEntry) + len * sizeof(WCHAR)); } }; diff --git a/src/coreclr/vm/gcenv.ee.cpp b/src/coreclr/vm/gcenv.ee.cpp index cabb60d009b085..606048446ee57e 100644 --- a/src/coreclr/vm/gcenv.ee.cpp +++ b/src/coreclr/vm/gcenv.ee.cpp @@ -1423,7 +1423,7 @@ bool GCToEEInterface::GetStringConfigValue(const char* privateKey, const char* p } size_t cchOut = u16_strlen(out) + 1; - int charCount = (int)minipal_get_length_utf16_to_utf8((const CHAR16_T*)out, cchOut, 0); + size_t charCount = minipal_get_length_utf16_to_utf8((const CHAR16_T*)out, cchOut, 0); if (charCount == 0) { // this should only happen if the config subsystem gives us a string that's not valid diff --git a/src/coreclr/vm/interoputil.cpp b/src/coreclr/vm/interoputil.cpp index 76d7bfc0dcab94..7452174a423263 100644 --- a/src/coreclr/vm/interoputil.cpp +++ b/src/coreclr/vm/interoputil.cpp @@ -606,7 +606,7 @@ HRESULT GetStringizedTypeLibGuidForAssembly(Assembly *pAssembly, CQuickArray INT_MAX) { + COMPlusThrowOM(); + } + return NewString(pwsz, (int)length); } STRINGREF StringObject::NewString(LPCUTF8 psz, int cBytes) @@ -706,16 +709,19 @@ STRINGREF StringObject::NewString(LPCUTF8 psz, int cBytes) if (cBytes == 0) { return GetEmptyString(); } - int cWszBytes = 0; - if (!ClrSafeInt::multiply(cBytes, sizeof(WCHAR), cWszBytes)) + S_SIZE_T cWszBytes = S_SIZE_T(cBytes) * S_SIZE_T(sizeof(WCHAR)); + if (cWszBytes.IsOverflow()) COMPlusThrowOM(); CQuickBytes qb; - WCHAR* pwsz = (WCHAR*) qb.AllocThrows(cWszBytes); - int length = (int)minipal_convert_utf8_to_utf16(psz, cBytes, (CHAR16_T*)pwsz, cBytes, 0); + WCHAR* pwsz = (WCHAR*) qb.AllocThrows(cWszBytes.Value()); + size_t length = minipal_convert_utf8_to_utf16(psz, cBytes, (CHAR16_T*)pwsz, cBytes, 0); if (length == 0) { COMPlusThrow(kArgumentException, W("Arg_InvalidUTF8String")); } - return NewString(pwsz, length); + if (length > INT_MAX) { + COMPlusThrowOM(); + } + return NewString(pwsz, (int)length); } // From 2da64d8fc7e83d46f7c59b72e5263098d686907d Mon Sep 17 00:00:00 2001 From: am11 <3840695+am11@users.noreply.github.com> Date: Sat, 7 Nov 2026 23:43:41 +0200 Subject: [PATCH 12/13] Simplify ReadUtf8 length check after minipal convert minipal_convert_utf16_to_utf8 cannot exceed the destination size; keep the assert instead of a redundant upper-bound check. Co-authored-by: Cursor --- src/coreclr/jit/helperexpansion.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 0e18085443da2b..b26dba3e0f9346 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -1719,15 +1719,17 @@ bool Compiler::fgVNBasedIntrinsicExpansionForCall_ReadUtf8(BasicBlock** pBlock, const size_t convertedLen = minipal_convert_utf16_to_utf8((const CHAR16_T*)bufferU16, srcLenCnsU16, (char*)bufferU8, MaxU8BufferSizeInBytes, 0); - if (convertedLen == 0 || convertedLen > (size_t)MaxU8BufferSizeInBytes) + if (convertedLen == 0) { // E.g. output buffer is too small - JITDUMP("ReadUtf8: minipal_convert_utf16_to_utf8 returned 0 or too large\n") + JITDUMP("ReadUtf8: minipal_convert_utf16_to_utf8 returned 0\n") return false; } - // Bounded by MaxU8BufferSizeInBytes above; narrow for the unsigned JIT helpers below. + // Narrow for the unsigned JIT helpers below. minipal_convert_utf16_to_utf8 cannot write + // more than MaxU8BufferSizeInBytes into the buffer. const unsigned srcLenU8 = (unsigned)convertedLen; + assert(srcLenU8 <= (unsigned)MaxU8BufferSizeInBytes); // Now that we know the exact UTF8 buffer length we can check if it's unrollable if (srcLenU8 > getUnrollThreshold(UnrollKind::Memcpy)) From 4dbd3511e4e76db00286588f0f0a7ac6736b5791 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid <3840695+am11@users.noreply.github.com> Date: Sun, 8 Nov 2026 17:54:48 +0200 Subject: [PATCH 13/13] Fix potential overflow in WCHAR allocation Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/coreclr/vm/object.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/object.cpp b/src/coreclr/vm/object.cpp index 479f83c037a736..77966a09ecbc93 100644 --- a/src/coreclr/vm/object.cpp +++ b/src/coreclr/vm/object.cpp @@ -681,7 +681,10 @@ STRINGREF StringObject::NewString(LPCUTF8 psz) return GetEmptyString(); } CQuickBytes qb; - WCHAR* pwsz = (WCHAR*) qb.AllocThrows(length * sizeof(WCHAR)); + S_SIZE_T cWszBytes = S_SIZE_T(length) * S_SIZE_T(sizeof(WCHAR)); + if (cWszBytes.IsOverflow()) + COMPlusThrowOM(); + WCHAR* pwsz = (WCHAR*) qb.AllocThrows(cWszBytes.Value()); length = minipal_convert_utf8_to_utf16(psz, length, (CHAR16_T*)pwsz, length, 0); if (length == 0) { COMPlusThrow(kArgumentException, W("Arg_InvalidUTF8String"));