Skip to content

Commit 690fda9

Browse files
authored
[SHLWAPI][SHLWAPI_APITEST] Rewrite StrToInt* functions (reactos#8591)
JIRA issue: CORE-19278 Reduce Wine test shlwapi:string failures. - Rewrite StrToIntA, StrToIntW, StrToIntExA, StrToInt64ExA, StrToIntExW, and StrToInt64ExW functions. - Add testcase StrToInt.
1 parent 3319a16 commit 690fda9

4 files changed

Lines changed: 324 additions & 0 deletions

File tree

dll/win32/shlwapi/string.c

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,9 @@ LPWSTR WINAPI StrStrNIW(LPCWSTR lpFirst, LPCWSTR lpSrch, UINT cchMax)
808808
return NULL;
809809
}
810810

811+
#ifdef __REACTOS__
812+
#define IS_DIGIT(c) ((UINT)(c) - '0' <= 9)
813+
#endif
811814
/*************************************************************************
812815
* StrToIntA [SHLWAPI.@]
813816
*
@@ -825,6 +828,28 @@ LPWSTR WINAPI StrStrNIW(LPCWSTR lpFirst, LPCWSTR lpSrch, UINT cchMax)
825828
*/
826829
int WINAPI StrToIntA(LPCSTR lpszStr)
827830
{
831+
#ifdef __REACTOS__
832+
if (!lpszStr)
833+
return 0;
834+
835+
INT result = 0;
836+
BOOL isNegative = FALSE;
837+
838+
if (*lpszStr == '-')
839+
{
840+
isNegative = TRUE;
841+
++lpszStr;
842+
}
843+
844+
while (IS_DIGIT(*lpszStr))
845+
{
846+
result *= 10;
847+
result += (*lpszStr - '0');
848+
++lpszStr;
849+
}
850+
851+
return isNegative ? -result : result;
852+
#else
828853
int iRet = 0;
829854

830855
TRACE("(%s)\n", debugstr_a(lpszStr));
@@ -838,6 +863,7 @@ int WINAPI StrToIntA(LPCSTR lpszStr)
838863
if (*lpszStr == '-' || isdigit(*lpszStr))
839864
StrToIntExA(lpszStr, 0, &iRet);
840865
return iRet;
866+
#endif
841867
}
842868

843869
/*************************************************************************
@@ -847,6 +873,28 @@ int WINAPI StrToIntA(LPCSTR lpszStr)
847873
*/
848874
int WINAPI StrToIntW(LPCWSTR lpszStr)
849875
{
876+
#ifdef __REACTOS__
877+
if (!lpszStr)
878+
return 0;
879+
880+
INT result = 0;
881+
BOOL isNegative = FALSE;
882+
883+
if (*lpszStr == L'-')
884+
{
885+
isNegative = TRUE;
886+
++lpszStr;
887+
}
888+
889+
while (IS_DIGIT(*lpszStr))
890+
{
891+
result *= 10;
892+
result += (*lpszStr - L'0');
893+
++lpszStr;
894+
}
895+
896+
return isNegative ? -result : result;
897+
#else
850898
int iRet = 0;
851899

852900
TRACE("(%s)\n", debugstr_w(lpszStr));
@@ -860,6 +908,7 @@ int WINAPI StrToIntW(LPCWSTR lpszStr)
860908
if (*lpszStr == '-' || isdigitW(*lpszStr))
861909
StrToIntExW(lpszStr, 0, &iRet);
862910
return iRet;
911+
#endif
863912
}
864913

865914
/*************************************************************************
@@ -891,7 +940,11 @@ BOOL WINAPI StrToIntExA(LPCSTR lpszStr, DWORD dwFlags, int *lpiRet)
891940
TRACE("(%s,%08X,%p)\n", debugstr_a(lpszStr), dwFlags, lpiRet);
892941

893942
bRes = StrToInt64ExA(lpszStr, dwFlags, &li);
943+
#ifdef __REACTOS__
944+
if (lpiRet) *lpiRet = bRes ? (INT)li : 0;
945+
#else
894946
if (bRes) *lpiRet = li;
947+
#endif
895948
return bRes;
896949
}
897950

@@ -902,6 +955,17 @@ BOOL WINAPI StrToIntExA(LPCSTR lpszStr, DWORD dwFlags, int *lpiRet)
902955
*/
903956
BOOL WINAPI StrToInt64ExA(LPCSTR lpszStr, DWORD dwFlags, LONGLONG *lpiRet)
904957
{
958+
#ifdef __REACTOS__
959+
if (!lpszStr)
960+
return FALSE;
961+
962+
WCHAR wideBuf[MAX_PATH];
963+
if (MultiByteToWideChar(CP_ACP, 0, lpszStr, -1, wideBuf, _countof(wideBuf)) <= 0)
964+
return FALSE;
965+
966+
wideBuf[_countof(wideBuf) - 1] = UNICODE_NULL; // SECURITY: Avoid buffer overrun
967+
return StrToInt64ExW(wideBuf, dwFlags, lpiRet);
968+
#else
905969
BOOL bNegative = FALSE;
906970
LONGLONG iRet = 0;
907971

@@ -960,6 +1024,7 @@ BOOL WINAPI StrToInt64ExA(LPCSTR lpszStr, DWORD dwFlags, LONGLONG *lpiRet)
9601024
}
9611025
*lpiRet = bNegative ? -iRet : iRet;
9621026
return TRUE;
1027+
#endif
9631028
}
9641029

9651030
/*************************************************************************
@@ -975,7 +1040,11 @@ BOOL WINAPI StrToIntExW(LPCWSTR lpszStr, DWORD dwFlags, int *lpiRet)
9751040
TRACE("(%s,%08X,%p)\n", debugstr_w(lpszStr), dwFlags, lpiRet);
9761041

9771042
bRes = StrToInt64ExW(lpszStr, dwFlags, &li);
1043+
#ifdef __REACTOS__
1044+
if (lpiRet) *lpiRet = bRes ? (INT)li : 0;
1045+
#else
9781046
if (bRes) *lpiRet = li;
1047+
#endif
9791048
return bRes;
9801049
}
9811050

@@ -986,6 +1055,66 @@ BOOL WINAPI StrToIntExW(LPCWSTR lpszStr, DWORD dwFlags, int *lpiRet)
9861055
*/
9871056
BOOL WINAPI StrToInt64ExW(LPCWSTR lpszStr, DWORD dwFlags, LONGLONG *lpiRet)
9881057
{
1058+
#ifdef __REACTOS__
1059+
if (!lpszStr)
1060+
return FALSE;
1061+
1062+
// Skip spaces
1063+
LPCWSTR pch = lpszStr;
1064+
while (*pch == L' ' || *pch == L'\n' || *pch == L'\t')
1065+
pch++;
1066+
1067+
BOOL isNegative = FALSE;
1068+
if (*pch == L'+' || *pch == L'-')
1069+
{
1070+
isNegative = (*pch == L'-');
1071+
++pch;
1072+
}
1073+
1074+
ULONGLONG value = 0;
1075+
LPCWSTR start = pch;
1076+
1077+
if ((dwFlags & STIF_SUPPORT_HEX) &&
1078+
*pch == L'0' && (pch[1] == L'x' || pch[1] == L'X')) // "0x" or "0X"
1079+
{
1080+
pch += 2;
1081+
start = pch;
1082+
for (;;)
1083+
{
1084+
INT digit;
1085+
if (IS_DIGIT(*pch)) digit = *pch - L'0';
1086+
else if (L'a' <= *pch && *pch <= L'f') digit = *pch - L'a' + 10;
1087+
else if (L'A' <= *pch && *pch <= L'F') digit = *pch - L'A' + 10;
1088+
else break;
1089+
1090+
value *= 16;
1091+
value += digit;
1092+
++pch;
1093+
}
1094+
isNegative = FALSE;
1095+
}
1096+
else
1097+
{
1098+
while (IS_DIGIT(*pch))
1099+
{
1100+
value *= 10;
1101+
value += (*pch - L'0');
1102+
++pch;
1103+
}
1104+
}
1105+
1106+
if (pch == start)
1107+
{
1108+
if (lpiRet)
1109+
*lpiRet = 0;
1110+
return FALSE; // No data
1111+
}
1112+
1113+
if (lpiRet)
1114+
*lpiRet = isNegative ? -(LONGLONG)value : (LONGLONG)value;
1115+
1116+
return TRUE;
1117+
#else
9891118
BOOL bNegative = FALSE;
9901119
LONGLONG iRet = 0;
9911120

@@ -1043,6 +1172,7 @@ BOOL WINAPI StrToInt64ExW(LPCWSTR lpszStr, DWORD dwFlags, LONGLONG *lpiRet)
10431172
}
10441173
*lpiRet = bNegative ? -iRet : iRet;
10451174
return TRUE;
1175+
#endif
10461176
}
10471177

10481178
/*************************************************************************

modules/rostests/apitests/shlwapi/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ list(APPEND SOURCE
2222
SHPropertyBag.cpp
2323
StrDup.c
2424
StrFormatByteSizeW.c
25+
StrToInt.c
2526
testdata.rc
2627
testlist.c)
2728

0 commit comments

Comments
 (0)