diff --git a/src/coreclr/debug/daccess/daccess.cpp b/src/coreclr/debug/daccess/daccess.cpp index 097c4ff170a80e..297fd552419fe7 100644 --- a/src/coreclr/debug/daccess/daccess.cpp +++ b/src/coreclr/debug/daccess/daccess.cpp @@ -95,20 +95,19 @@ 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(); - } + size_t cchName = minipal_get_length_utf8_to_utf16(utf8, cchUtf8, 0); + *nameLen = (ULONG32)cchName; } 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,20 +119,23 @@ 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; + 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]; @@ -142,10 +144,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 449e64f7ee8b7c..549a421b0c0569 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/mscordac/mscordac_unixexports.src b/src/coreclr/dlls/mscordac/mscordac_unixexports.src index b1edc440164e6f..b21c32431ad380 100644 --- a/src/coreclr/dlls/mscordac/mscordac_unixexports.src +++ b/src/coreclr/dlls/mscordac/mscordac_unixexports.src @@ -76,7 +76,6 @@ nativeStringResourceTable_mscorrc #GetSystemInfo #LoadLibraryExA #LoadLibraryExW -#MultiByteToWideChar #OutputDebugStringW #OutputDebugStringA #RaiseException @@ -86,6 +85,5 @@ nativeStringResourceTable_mscorrc #SetThreadDescription #SwitchToThread #TerminateProcess -#WideCharToMultiByte #GUID_NULL diff --git a/src/coreclr/dlls/mscoree/exports.cpp b/src/coreclr/dlls/mscoree/exports.cpp index ebe873e80bf59e..24ccdf5d250727 100644 --- a/src/coreclr/dlls/mscoree/exports.cpp +++ b/src/coreclr/dlls/mscoree/exports.cpp @@ -133,13 +133,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/gc/gccommon.cpp b/src/coreclr/gc/gccommon.cpp index e1827fb37b5e48..9825efb7d780b3 100644 --- a/src/coreclr/gc/gccommon.cpp +++ b/src/coreclr/gc/gccommon.cpp @@ -12,6 +12,7 @@ #include "gcenv.h" #include "gc.h" +#include IGCHeapInternal* g_theGCHeap; IGCHandleManager* g_theGCHandleManager; @@ -131,7 +132,16 @@ FILE* CreateLogFile(const GCConfigStringHolder& temp_logfile_name, bool is_confi const char* suffix = is_config ? ".config.log" : ".log"; //_snprintf_s(logfile_name, MAX_LONGPATH+1, _TRUNCATE, "%s.%d%s", temp_logfile_name.Get(), pid, suffix); _snprintf_s(logfile_name, MAX_LONGPATH+1, _TRUNCATE, "%s%s", temp_logfile_name.Get(), suffix); +#ifdef TARGET_WINDOWS + // Config strings are UTF-8; fopen would interpret them as the ANSI code page. + size_t nameLen = strlen(logfile_name) + 1; + size_t wlen = minipal_get_length_utf8_to_utf16(logfile_name, nameLen, 0); + WCHAR* wpath = (WCHAR*)_alloca(wlen * sizeof(WCHAR)); + minipal_convert_utf8_to_utf16(logfile_name, nameLen, (CHAR16_T*)wpath, wlen, 0); + logFile = _wfopen(wpath, L"wb"); +#else logFile = fopen(logfile_name, "wb"); +#endif if (logFile == NULL) { 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 aa576898fd8c14..9ff8598799af43 100644 --- a/src/coreclr/ilasm/asmparse.h +++ b/src/coreclr/ilasm/asmparse.h @@ -106,9 +106,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..b178543e48e370 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); + 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); @@ -1403,8 +1402,8 @@ 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); - 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; @@ -1413,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 5096bbdda453fa..3c45d0fc655ff8 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) @@ -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 ? MultiByteToWideChar(g_uCodePage,0,(char*)pb,-1,UnicodeString,DataLen+1) : 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)) @@ -2412,7 +2413,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 a66f8543d0b176..419dda757690d1 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; } } @@ -1814,15 +1814,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 b6df0cfdd0c19a..ae417d4363850d 100644 --- a/src/coreclr/ilasm/main.cpp +++ b/src/coreclr/ilasm/main.cpp @@ -56,7 +56,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) { @@ -98,14 +97,14 @@ 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) { #ifdef TARGET_UNIX char szFileName[MAX_FILENAME_LENGTH*3]; - WideCharToMultiByte(uCodePage,0,wzFileName,-1,szFileName,MAX_FILENAME_LENGTH*3-1,NULL,NULL); + minipal_convert_utf16_to_utf8((const CHAR16_T*)wzFileName,u16_strlen(wzFileName)+1,szFileName,MAX_FILENAME_LENGTH*3-1,0); char szCwd[PATH_MAX]; char szFullPath[PATH_MAX + MAX_FILENAME_LENGTH*3]; if((szFileName[0] != '/') && (getcwd(szCwd, sizeof(szCwd)) != NULL)) @@ -117,7 +116,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); #endif char* sz = new char[strlen(szFullPath)+1]; if(sz) strcpy_s(sz,strlen(szFullPath)+1,szFullPath); @@ -155,7 +154,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)); @@ -238,7 +236,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; @@ -334,7 +333,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; @@ -702,7 +701,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); } } @@ -904,13 +903,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 da3e32142410c2..cd9d7e4d7f2a23 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; AStringHolder 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 68949122909291..27a3c006947a72 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 04d95e3e01781c..e89547335044cc 100644 --- a/src/coreclr/ildasm/dis.cpp +++ b/src/coreclr/ildasm/dis.cpp @@ -91,7 +91,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; } @@ -100,7 +100,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; } @@ -109,7 +109,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; } @@ -118,7 +118,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; } @@ -727,7 +727,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; @@ -1069,7 +1069,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 6e33c86ceeed0a..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 @@ -144,7 +144,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); @@ -429,7 +429,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); @@ -506,7 +506,7 @@ int main(int argc, char* argv[]) g_fHideFOA = FALSE; g_fHidePrivScope = FALSE; } - 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/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 461b6dccbd5463..b26dba3e0f9346 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -1717,21 +1717,22 @@ 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) { // 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\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); + // 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 > (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/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..81ab95b96ae107 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. - int iLen; // A length. + size_t cchName; // Length of the name, including the terminator. + size_t 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 = 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..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(); @@ -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 = minipal_get_length_utf8_to_utf16(pVer, cchVer, 0); + } + else + { + // Attempt to convert into caller's buffer. + 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 = 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 @@ -3009,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 0fc2b8b041d817..ea568f67d22724 100644 --- a/src/coreclr/md/enc/metamodelrw.cpp +++ b/src/coreclr/md/enc/metamodelrw.cpp @@ -3819,7 +3819,8 @@ CMiniMdRW::Impl_GetStringW( ULONG *pcchBuffer) { LPCSTR szString; // Single byte version. - int iSize; // Size of resulting string, in wide chars. + size_t cchString; // Length of the single byte version, including the terminator. + size_t iSize; // Size of resulting string, in wide chars. HRESULT hr = NOERROR; IfFailGo(getString(ix, &szString)); @@ -3833,18 +3834,19 @@ 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 = minipal_get_length_utf8_to_utf16(szString, cchString, 0); + else + iSize = szOut != NULL ? minipal_convert_utf8_to_utf16(szString, cchString, (CHAR16_T*)szOut, cchBuffer, 0) : 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); + { + 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 @@ -3855,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/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..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 = ::WideCharToMultiByte(CP_ACP, 0, szStreamName, -1, 0, 0, 0, 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; @@ -445,7 +447,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 +643,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..ca327f28a49b4a 100644 --- a/src/coreclr/md/runtime/metamodelro.cpp +++ b/src/coreclr/md/runtime/metamodelro.cpp @@ -102,7 +102,8 @@ CMiniMd::Impl_GetStringW( ULONG *pcchBuffer) { LPCSTR szString; // Single byte version. - int iSize; // Size of resulting string, in wide chars. + size_t cchString; // Length of the single byte version, including the terminator. + size_t iSize; // Size of resulting string, in wide chars. HRESULT hr = NOERROR; IfFailGo(getString(ix, &szString)); @@ -116,19 +117,19 @@ CMiniMd::Impl_GetStringW( *pcchBuffer = 0; goto ErrExit; } - iSize = ::MultiByteToWideChar(CP_UTF8, 0, szString, -1, szOut, cchBuffer); + cchString = strlen(szString) + 1; + if (cchBuffer == 0) + iSize = minipal_get_length_utf8_to_utf16(szString, cchString, 0); + else + iSize = szOut != NULL ? minipal_convert_utf8_to_utf16(szString, cchString, (CHAR16_T*)szOut, cchBuffer, 0) : 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); + { + 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 @@ -139,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 d0d3524ae6ea88..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); @@ -986,38 +986,22 @@ 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 = 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 = ::WideCharToMultiByte( - CP_UTF8, - 0, - szString, - -1, - pData, - GetCbSegAvailable(), - NULL, - NULL); + iLen = 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) @@ -1031,7 +1015,7 @@ StgStringPool::AddStringW( if (pHash->iOffset == 0xffffffff) { *pnOffset = pHash->iOffset = GetNextOffset(); - SegAllocate(iLen); + SegAllocate((ULONG)iLen); } // Else use the old one. else @@ -1043,7 +1027,7 @@ StgStringPool::AddStringW( else { *pnOffset = GetNextOffset(); - SegAllocate(iLen); + SegAllocate((ULONG)iLen); } return (S_OK); } // StgStringPool::AddStringW 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..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. @@ -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 = 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 @@ -64,7 +63,7 @@ int LoadNativeStringResource(const NativeStringResourceTable &nativeStringResour if (nxt != NULL) { - len = (int)(nxt - szBuffer); + len = (size_t)(nxt - szBuffer); } else { @@ -79,7 +78,7 @@ int LoadNativeStringResource(const NativeStringResourceTable &nativeStringResour if (pcwchUsed) { - *pcwchUsed = len; + *pcwchUsed = (int)len; } return S_OK; diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index ff0fdc732d83f7..8e3e3b0b0a4051 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -433,11 +433,6 @@ typedef struct _OVERLAPPED { #define STD_OUTPUT_HANDLE ((DWORD)-11) #define STD_ERROR_HANDLE ((DWORD)-12) -PALIMPORT -UINT -PALAPI -GetConsoleOutputCP(); - PALIMPORT DWORD PALAPI @@ -1994,44 +1989,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 9272d2f18bf4b0..543e6802855237 100644 --- a/src/coreclr/pal/src/CMakeLists.txt +++ b/src/coreclr/pal/src/CMakeLists.txt @@ -154,7 +154,6 @@ set(SOURCES init/pal.cpp init/sxs.cpp loader/module.cpp - locale/unicode.cpp misc/cgroup.cpp misc/dbgmsg.cpp misc/environ.cpp diff --git a/src/coreclr/pal/src/cruntime/wchar.cpp b/src/coreclr/pal/src/cruntime/wchar.cpp index aa44b2adc87ef8..7ddcce37ad3e3a 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); @@ -36,17 +37,17 @@ __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 = WideCharToMultiByte(CP_ACP, 0, string, -1, 0, 0, 0, 0); + len = 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; } @@ -57,10 +58,10 @@ _wtoi( SetLastError(ERROR_NOT_ENOUGH_MEMORY); return -1; } - len = WideCharToMultiByte(CP_ACP, 0, string, -1, tempStr, len, 0, 0); + len = 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; @@ -240,18 +241,18 @@ 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 = WideCharToMultiByte(CP_ACP, 0, nptr, -1, NULL, 0, NULL, NULL); + size = minipal_get_length_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, 0); 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; @@ -264,11 +265,11 @@ PAL_wcstoul( res = 0; goto PAL_wcstoulExit; } - size = WideCharToMultiByte(CP_ACP, 0, nptr, -1, s_nptr, size, NULL, NULL); + size = minipal_convert_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, s_nptr, size, 0); 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; @@ -330,18 +331,18 @@ 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 = WideCharToMultiByte(CP_ACP, 0, nptr, -1, NULL, 0, NULL, NULL); + size = minipal_get_length_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, 0); 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; @@ -354,11 +355,11 @@ PAL__wcstoui64( res = 0; goto PAL__wcstoui64Exit; } - size = WideCharToMultiByte(CP_ACP, 0, nptr, -1, s_nptr, size, NULL, NULL); + size = minipal_convert_utf16_to_utf8((const CHAR16_T*)nptr, PAL_wcslen(nptr) + 1, s_nptr, size, 0); 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; @@ -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 cdf7e58cc1f03d..0a7097bbccdcf6 100644 --- a/src/coreclr/pal/src/debug/debug.cpp +++ b/src/coreclr/pal/src/debug/debug.cpp @@ -24,6 +24,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 @@ -170,7 +171,7 @@ OutputDebugStringW( IN LPCWSTR lpOutputString) { CHAR *lpOutputStringA; - int strLen; + size_t strLen; PERF_ENTRY(OutputDebugStringW); ENTRY("OutputDebugStringW (lpOutputString=%p (%S))\n", @@ -183,8 +184,7 @@ OutputDebugStringW( goto EXIT; } - if ((strLen = WideCharToMultiByte(CP_ACP, 0, lpOutputString, -1, NULL, 0, - NULL, NULL)) + 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"); @@ -200,8 +200,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/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/include/pal/utils.h b/src/coreclr/pal/src/include/pal/utils.h index 2636f04db4cf5f..5a79a099a12d07 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 e7ce5834ff974e..0fb193f9da1175 100644 --- a/src/coreclr/pal/src/init/pal.cpp +++ b/src/coreclr/pal/src/init/pal.cpp @@ -21,6 +21,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" @@ -691,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) @@ -704,10 +705,10 @@ 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 = 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; } @@ -719,10 +720,9 @@ 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"); + 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 e1c9501da5021d..d0159ffad21a48 100644 --- a/src/coreclr/pal/src/loader/module.cpp +++ b/src/coreclr/pal/src/loader/module.cpp @@ -28,6 +28,7 @@ SET_DEFAULT_DEBUG_CHANNEL(LOADER); // some headers have code with asserts, so do #include "pal/init.h" #include "pal/environ.h" #include "pal/stackstring.hpp" +#include #include #include @@ -381,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", @@ -404,9 +406,8 @@ 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); - 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,14 +1295,14 @@ static bool LOADConvertLibraryPathWideStringToMultibyteString( _ASSERTE(wideLibraryPath != nullptr); size_t length = (PAL_wcslen(wideLibraryPath)+1) * MaxWCharToAcpLengthFactor; - *multibyteLibraryPathLengthRef = WideCharToMultiByte(CP_ACP, 0, wideLibraryPath, -1, multibyteLibraryPath, - length, nullptr, nullptr); + 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) { 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 d163f851676c9d..00000000000000 --- a/src/coreclr/pal/src/locale/unicode.cpp +++ /dev/null @@ -1,221 +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 -#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 0b3c0181bc4839..015cb277b42974 100644 --- a/src/coreclr/pal/src/misc/dbgmsg.cpp +++ b/src/coreclr/pal/src/misc/dbgmsg.cpp @@ -72,7 +72,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 919496a124f7bb..a42ccb1c8c0396 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 @@ -154,7 +155,7 @@ GetEnvironmentVariableW( { CHAR *inBuff = nullptr; CHAR *outBuff = nullptr; - INT inBuffSize; + size_t inBuffSize; DWORD size = 0; PERF_ENTRY(GetEnvironmentVariableW); @@ -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 ? 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,10 +190,9 @@ 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"); + ASSERT("UTF-16 to UTF-8 conversion failed!\n"); SetLastError(ERROR_INTERNAL_ERROR); goto done; } @@ -215,7 +214,8 @@ GetEnvironmentVariableW( } else { - size = MultiByteToWideChar(CP_ACP, 0, outBuff, -1, lpBuffer, nSize); + 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. @@ -223,7 +223,7 @@ GetEnvironmentVariableW( } else { - ASSERT("MultiByteToWideChar failed!\n"); + ASSERT("UTF-8 to UTF-16 conversion failed!\n"); SetLastError(ERROR_INTERNAL_ERROR); size = 0; *lpBuffer = '\0'; @@ -281,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); @@ -290,10 +290,9 @@ 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 ? 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,20 +305,18 @@ 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"); + ASSERT("UTF-16 to UTF-8 conversion returned 0\n"); SetLastError(ERROR_INTERNAL_ERROR); goto done; } if (lpValue != nullptr) { - if ((valueSize = WideCharToMultiByte(CP_ACP, 0, lpValue, -1, value, - 0, nullptr, nullptr)) == 0) + if ((valueSize = 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; } @@ -333,10 +330,9 @@ 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"); + ASSERT("UTF-16 to UTF-8 conversion failed\n"); SetLastError( ERROR_INTERNAL_ERROR ); goto done; } @@ -384,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"); @@ -398,7 +395,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 = minipal_get_length_utf8_to_utf16(palEnvironment[i], strlen(palEnvironment[i]) + 1, 0); envNum += len; } @@ -414,7 +411,7 @@ GetEnvironmentStringsW( tempEnviron = wenviron; for (i = 0; palEnvironment[i] != 0; i++) { - len = MultiByteToWideChar(CP_ACP, 0, palEnvironment[i], -1, tempEnviron, envNum); + 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 f096156f23847e..c578639080aa7e 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" @@ -104,12 +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 = WideCharToMultiByte( CP_ACP, 0, str, -1, buf, - MAX_NUMBER_LENGTH, NULL, 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 c9f5ba80a78d9b..5bd995307518e8 100644 --- a/src/coreclr/pal/src/misc/utils.cpp +++ b/src/coreclr/pal/src/misc/utils.cpp @@ -26,6 +26,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 @@ -46,18 +47,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) { - int length; + size_t cchSource = cchWideChar < 0 ? PAL_wcslen(lpWideCharStr) + 1 : (size_t)cchWideChar; + size_t length; LPSTR lpMultiByteStr; /* get required buffer length */ - length = WideCharToMultiByte(CP_ACP, 0, lpWideCharStr, cchWideChar, - NULL, 0, NULL, NULL); + length = minipal_get_length_utf16_to_utf8((const CHAR16_T*)lpWideCharStr, cchSource, 0); if(0 == length) { ERROR("WCToMB error; GetLastError returns %#x", GetLastError()); @@ -74,8 +75,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 = minipal_convert_utf16_to_utf8((const CHAR16_T*)lpWideCharStr, cchSource, lpMultiByteStr, length, 0); if(0 == length) { ASSERT("WCToMB error; GetLastError returns %#x\n", GetLastError()); @@ -98,18 +98,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) { - int length; + size_t cbSource = cbMultiByte < 0 ? strlen(lpMultiByteStr) + 1 : (size_t)cbMultiByte; + size_t length; LPWSTR lpWideCharStr; /* get required buffer length */ - length = MultiByteToWideChar(CP_ACP, 0, lpMultiByteStr, cbMultiByte, - NULL, 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,9 +134,8 @@ LPWSTR UTIL_MBToWC_Alloc(LPCSTR lpMultiByteStr, int cbMultiByte) } /* convert into allocated buffer */ - length = MultiByteToWideChar(CP_ACP, 0, lpMultiByteStr, cbMultiByte, - lpWideCharStr, length); - 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 cb21db893f0f49..f5d80cbf0063c4 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 @@ -1302,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); @@ -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 ? 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 || 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/CMakeLists.txt b/src/coreclr/pal/tests/palsuite/CMakeLists.txt index e1362b3e39a900..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,32 +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 - 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/test2/test.cpp miscellaneous/FlushInstructionCache/test1/test1.cpp miscellaneous/FormatMessageW/test1/test.cpp @@ -234,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 @@ -250,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 @@ -272,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/common/palsuite.cpp b/src/coreclr/pal/tests/palsuite/common/palsuite.cpp index 1b5f826dd8d9f9..88fe3fa77a2974 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; } diff --git a/src/coreclr/pal/tests/palsuite/compilableTests.txt b/src/coreclr/pal/tests/palsuite/compilableTests.txt index 76c53595367098..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,24 +66,10 @@ 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 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/test2/paltest_closehandle_test2 miscellaneous/FlushInstructionCache/test1/paltest_flushinstructioncache_test1 miscellaneous/FormatMessageW/test1/paltest_formatmessagew_test1 @@ -172,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 @@ -194,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/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/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 afd899d6d46468..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,20 +62,9 @@ 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 -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/test2/paltest_closehandle_test2 miscellaneous/FlushInstructionCache/test1/paltest_flushinstructioncache_test1 miscellaneous/FormatMessageW/test1/paltest_formatmessagew_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 aa4324c318988f..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,32 +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 -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 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 ); - -} diff --git a/src/coreclr/scripts/genLttngProvider.py b/src/coreclr/scripts/genLttngProvider.py index 24030925a22cdf..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,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 = 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 6fdc11a30ce89b..a4333df63b6147 100644 --- a/src/coreclr/tools/metainfo/mdobj.cpp +++ b/src/coreclr/tools/metainfo/mdobj.cpp @@ -204,8 +204,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 66c2f46a7ef768..60e1527b8f59cf 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,12 @@ LPWSTR verbMerge::MergePathStrings(LPCWSTR dir, LPCWSTR file) return newpath; } -char* verbMerge::ConvertWideCharToMultiByte(LPCWSTR wstr) +WCHAR* verbMerge::ConvertFromUtf8(LPCSTR str) { - 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); - return encodedStr; -} - -WCHAR* verbMerge::ConvertMultiByteToWideChar(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,20 +65,20 @@ int verbMerge::AppendFileRaw(FILE* hFileOut, LPCWSTR fileFullPath, unsigned char { int result = 0; // default to zero == success - char* fileNameAsChar = ConvertWideCharToMultiByte(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; } @@ -96,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; } @@ -111,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); @@ -134,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 = ConvertWideCharToMultiByte(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"); @@ -318,7 +307,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. @@ -502,26 +491,23 @@ int verbMerge::AppendAllInDir(FILE* hFileOut, #else // TARGET_WINDOWS struct stat fileStat; - char *fileFullPathUtf8 = ConvertWideCharToMultiByte(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 = ConvertWideCharToMultiByte(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 { @@ -612,13 +598,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); FILE* hFileOut = fopen(nameOfOutputFile, "wb"); if (hFileOut == nullptr) diff --git a/src/coreclr/tools/superpmi/mcs/verbmerge.h b/src/coreclr/tools/superpmi/mcs/verbmerge.h index e03ad869600ca1..c02a4bd4958d17 100644 --- a/src/coreclr/tools/superpmi/mcs/verbmerge.h +++ b/src/coreclr/tools/superpmi/mcs/verbmerge.h @@ -80,8 +80,7 @@ class verbMerge static LPWSTR MergePathStrings(LPCWSTR dir, LPCWSTR file); - static char* ConvertWideCharToMultiByte(LPCWSTR wstr); - static WCHAR* ConvertMultiByteToWideChar(LPCSTR str); + static WCHAR* ConvertFromUtf8(LPCSTR str); static int AppendFileRaw(FILE* hFileOut, LPCWSTR fileFullPath, unsigned char* buffer, size_t bufferSize); static int AppendFile(FILE* 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..8329fbd6bb5964 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(); + 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); - 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,24 @@ 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); + size_t cchNeed = minipal_get_length_utf8_to_utf16(pString, length, 0); + *pcNeedChars = (COUNT_T)cchNeed; } 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/util.cpp b/src/coreclr/utilcode/util.cpp index ee97461e39d2ec..c107192b94cf52 100644 --- a/src/coreclr/utilcode/util.cpp +++ b/src/coreclr/utilcode/util.cpp @@ -1622,9 +1622,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 ) { @@ -1634,7 +1634,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); @@ -1647,21 +1647,31 @@ 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; + 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 = MultiByteToWideChar(CP_UTF8, 0, pStr, -1, 0, 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); @@ -1674,8 +1684,8 @@ 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())); - _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 38d82e2a5c1149..4c02d60c09dfc7 100644 --- a/src/coreclr/vm/assemblyspec.cpp +++ b/src/coreclr/vm/assemblyspec.cpp @@ -427,12 +427,12 @@ 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()); - 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()); + size_t cchLocale = strlen(m_context.szLocale) + 1; + 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 { 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 66aaa273713651..efe4c7f4966ebd 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/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 a1772c8a4fdef6..ea5504c80cb67b 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 @@ -120,21 +127,20 @@ 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 = MultiByteToWideChar(CP_ACP, 0, utf8Name, -1, name, sizeRemaining - sizeof(EventStaticEntry)); - if (len <= 0) + len = 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 < MaxEntrySize()) 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; } @@ -157,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 22f762a1d4ec52..75cc80ea378686 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,20 +1408,22 @@ 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; } out = Configuration::GetKnobStringValue(configKey); - if (out == NULL) - { - return false; - } } } - int charCount = WideCharToMultiByte(CP_ACP, 0, out, -1 /* out is null-terminated */, NULL, 0, nullptr, nullptr); + if (out == NULL) + { + return false; + } + + size_t cchOut = u16_strlen(out) + 1; + 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 @@ -1444,10 +1446,9 @@ bool GCToEEInterface::GetStringConfigValue(const char* privateKey, const char* p return false; } - if (WideCharToMultiByte(CP_ACP, 0, out, -1 /* out is null-terminated */, - configResult, charCount, nullptr, nullptr) == 0) + if (minipal_convert_utf16_to_utf8((const CHAR16_T*)out, cchOut, configResult, 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 abc16988b468f0..e456402e853e6b 100644 --- a/src/coreclr/vm/gdbjit.cpp +++ b/src/coreclr/vm/gdbjit.cpp @@ -522,11 +522,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; } @@ -554,7 +555,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; @@ -2511,11 +2512,12 @@ 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); + size_t cchModuleFile = strlen(szModuleFile) + 1; + size_t length = minipal_get_length_utf8_to_utf16(szModuleFile, cchModuleFile, 0); if (length == 0) return; WStringHolder wszModuleFile(new WCHAR[length+1]); - length = MultiByteToWideChar(CP_UTF8, 0, szModuleFile, -1, wszModuleFile, length); + length = minipal_convert_utf8_to_utf16(szModuleFile, cchModuleFile, (CHAR16_T*)(WCHAR*)wszModuleFile, length, 0); if (length == 0) return; diff --git a/src/coreclr/vm/interoputil.cpp b/src/coreclr/vm/interoputil.cpp index 6c1a4dbb61242d..9e96bf28f006aa 100644 --- a/src/coreclr/vm/interoputil.cpp +++ b/src/coreclr/vm/interoputil.cpp @@ -606,7 +606,7 @@ 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 = 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 INT_MAX) { + COMPlusThrowOM(); + } + return NewString(pwsz, (int)length); } STRINGREF StringObject::NewString(LPCUTF8 psz, int cBytes) @@ -706,16 +712,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 = MultiByteToWideChar(CP_UTF8, 0, psz, cBytes, pwsz, cBytes); + 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); } // diff --git a/src/coreclr/vm/util.cpp b/src/coreclr/vm/util.cpp index f429dea34d7ce4..631ee85a365d78 100644 --- a/src/coreclr/vm/util.cpp +++ b/src/coreclr/vm/util.cpp @@ -135,6 +135,7 @@ void PrintToStdErrW(const WCHAR *pwzString) } CONTRACTL_END +#ifdef TARGET_WINDOWS UINT codePage = GetConsoleOutputCP(); // Console output allows best-fit mapping and default-character substitution. int byteCount = WideCharToMultiByte(codePage, 0, pwzString, -1, nullptr, 0, nullptr, nullptr); @@ -149,6 +150,14 @@ void PrintToStdErrW(const WCHAR *pwzString) { 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); } 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); 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/minipal/CMakeLists.txt b/src/tests/minipal/CMakeLists.txt new file mode 100644 index 00000000000000..445487d2000ce8 --- /dev/null +++ b/src/tests/minipal/CMakeLists.txt @@ -0,0 +1,20 @@ +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}) + +set(NATIVE_TEST_COMMON_DIR ../tracing/eventpipe/native/common) + +add_executable(NativeMinipalTestsDriver + ${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 ${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/minipal/NativeMinipalTests.cs b/src/tests/minipal/NativeMinipalTests.cs new file mode 100644 index 00000000000000..23a678bad86c18 --- /dev/null +++ b/src/tests/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/minipal/NativeMinipalTests.csproj b/src/tests/minipal/NativeMinipalTests.csproj new file mode 100644 index 00000000000000..03acd75ea79f36 --- /dev/null +++ b/src/tests/minipal/NativeMinipalTests.csproj @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/tests/minipal/native-minipal-tests-driver.c b/src/tests/minipal/native-minipal-tests-driver.c new file mode 100644 index 00000000000000..59899dba334103 --- /dev/null +++ b/src/tests/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/minipal/utf8-tests.c b/src/tests/minipal/utf8-tests.c new file mode 100644 index 00000000000000..49b2aad3ade1d2 --- /dev/null +++ b/src/tests/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)