From 1e644fc37ef3bb169e8be886796c0f7e90461d83 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 10 Dec 2018 12:39:32 +0100 Subject: [PATCH 1/3] Added _wcsnlen function for WCHAR string length. --- winpr/include/winpr/string.h | 2 ++ winpr/libwinpr/crt/string.c | 69 +++++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 25 deletions(-) diff --git a/winpr/include/winpr/string.h b/winpr/include/winpr/string.h index 7ce889a51..166d800b6 100644 --- a/winpr/include/winpr/string.h +++ b/winpr/include/winpr/string.h @@ -58,6 +58,8 @@ WINPR_API int _strnicmp(const char* string1, const char* string2, size_t count); WINPR_API int _wcscmp(const WCHAR* string1, const WCHAR* string2); WINPR_API size_t _wcslen(const WCHAR* str); +WINPR_API size_t _wcsnlen(const WCHAR* str, size_t numberOfElements); + WINPR_API WCHAR* _wcschr(const WCHAR* str, WCHAR c); WINPR_API WCHAR* _wcsrchr(const WCHAR* str, WCHAR c); diff --git a/winpr/libwinpr/crt/string.c b/winpr/libwinpr/crt/string.c index aa70212b7..d30ac110c 100644 --- a/winpr/libwinpr/crt/string.c +++ b/winpr/libwinpr/crt/string.c @@ -45,7 +45,7 @@ char* _strdup(const char* strSource) strDestination = strdup(strSource); if (strDestination == NULL) - WLog_ERR(TAG,"strdup"); + WLog_ERR(TAG, "strdup"); return strDestination; } @@ -68,7 +68,7 @@ WCHAR* _wcsdup(const WCHAR* strSource) #endif if (strDestination == NULL) - WLog_ERR(TAG,"wcsdup"); + WLog_ERR(TAG, "wcsdup"); return strDestination; } @@ -104,7 +104,7 @@ int _wcscmp(const WCHAR* string1, const WCHAR* string2) size_t _wcslen(const WCHAR* str) { - WCHAR* p = (WCHAR*) str; + const WCHAR* p = (const WCHAR*) str; if (!p) return 0; @@ -112,17 +112,36 @@ size_t _wcslen(const WCHAR* str) while (*p) p++; - return (p - str); + return (size_t)(p - str); } +/* _wcsnlen -> wcsnlen */ + +size_t _wcsnlen(const WCHAR* str, size_t max) +{ + size_t x; + + if (!str) + return 0; + + for (x = 0; x < max; x++) + { + if (str[x] == 0) + return x; + } + + return x; +} + + /* _wcschr -> wcschr */ WCHAR* _wcschr(const WCHAR* str, WCHAR c) { WCHAR* p = (WCHAR*) str; WCHAR value; - Data_Write_UINT16(&value, c); + while (*p && (*p != value)) p++; @@ -133,15 +152,15 @@ WCHAR* _wcschr(const WCHAR* str, WCHAR c) WCHAR* _wcsrchr(const WCHAR* str, WCHAR c) { - WCHAR *p; + WCHAR* p; WCHAR ch; if (!str) return NULL; - for (p = (WCHAR *) 0; (ch = *str); str++) + for (p = (WCHAR*) 0; (ch = *str); str++) if (ch == c) - p = (WCHAR *) str; + p = (WCHAR*) str; return p; } @@ -160,6 +179,7 @@ WCHAR* wcstok_s(WCHAR* strToken, const WCHAR* strDelimit, WCHAR** context) strToken = *context; Data_Read_UINT16(strToken, value); + while (*strToken && _wcschr(strDelimit, value)) { strToken++; @@ -170,8 +190,8 @@ WCHAR* wcstok_s(WCHAR* strToken, const WCHAR* strDelimit, WCHAR** context) return NULL; nextToken = strToken++; - Data_Read_UINT16(strToken, value); + while (*strToken && !(_wcschr(strDelimit, value))) { strToken++; @@ -352,7 +372,7 @@ BOOL IsCharAlphaW(WCHAR ch) BOOL IsCharAlphaNumericA(CHAR ch) { if (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || - ((ch >= '0') && (ch <= '9'))) + ((ch >= '0') && (ch <= '9'))) return 1; else return 0; @@ -409,7 +429,7 @@ int lstrlenW(LPCWSTR lpString) while (*p) p++; - return (int) (p - lpString); + return (int)(p - lpString); } int lstrcmpA(LPCSTR lpString1, LPCSTR lpString2) @@ -440,7 +460,6 @@ int ConvertLineEndingToLF(char* str, int size) char* end; char* pInput; char* pOutput; - end = &str[size]; pInput = pOutput = str; @@ -457,8 +476,7 @@ int ConvertLineEndingToLF(char* str, int size) } } - status = (int) (pOutput - str); - + status = (int)(pOutput - str); return status; } @@ -469,9 +487,7 @@ char* ConvertLineEndingToCRLF(const char* str, int* size) char* pOutput; const char* end; const char* pInput; - end = &str[*size]; - count = 0; pInput = str; @@ -506,8 +522,7 @@ char* ConvertLineEndingToCRLF(const char* str, int* size) pInput++; } - *size = (int) (pOutput - newStr); - + *size = (int)(pOutput - newStr); return newStr; } @@ -515,7 +530,6 @@ char* StrSep(char** stringp, const char* delim) { char* start = *stringp; char* p; - p = (start != NULL) ? strpbrk(start, delim) : NULL; if (!p) @@ -533,7 +547,7 @@ INT64 GetLine(char** lineptr, size_t* size, FILE* stream) { #if defined(_WIN32) char c; - char *n; + char* n; size_t step = 32; size_t used = 0; @@ -549,18 +563,23 @@ INT64 GetLine(char** lineptr, size_t* size, FILE* stream) { *size += step; n = realloc(*lineptr, *size); + if (!n) { return -1; } + *lineptr = n; } - c = fgetc(stream); - if (c != EOF) - (*lineptr)[used++] = c; - } while((c != '\n') && (c != '\r') && (c != EOF)); - (*lineptr)[used] = '\0'; + c = fgetc(stream); + + if (c != EOF) + (*lineptr)[used++] = c; + } + while ((c != '\n') && (c != '\r') && (c != EOF)); + + (*lineptr)[used] = '\0'; return used; #elif !defined(ANDROID) && !defined(IOS) return getline(lineptr, size, stream); From d198f730817283e830d9394a43fe6f23800830a5 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 10 Dec 2018 12:41:04 +0100 Subject: [PATCH 2/3] Fix #5121: Determine actual string length for input data ConvertFromUnicode ignores '\0' sequences when the length of the input string is given. Clipboard strings may be larger than the actual string length and padded with random data leading to decoding errors. Limit the length to the first occurrence of a '\0'. --- winpr/libwinpr/clipboard/synthetic.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/winpr/libwinpr/clipboard/synthetic.c b/winpr/libwinpr/clipboard/synthetic.c index 981cc566e..52606b1fc 100644 --- a/winpr/libwinpr/clipboard/synthetic.c +++ b/winpr/libwinpr/clipboard/synthetic.c @@ -46,14 +46,15 @@ static void* clipboard_synthesize_cf_text(wClipboard* clipboard, UINT32 formatId if (formatId == CF_UNICODETEXT) { + size_t wsize; char* str = NULL; if (*pSize > INT32_MAX) return NULL; - size = (int) * pSize; - size = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) data, - size / 2, (CHAR**) &str, 0, NULL, NULL); + wsize = _wcsnlen(data, (*pSize) / 2); + size = ConvertFromUnicode(CP_UTF8, 0, (LPCWSTR) data, + wsize, (CHAR**) &str, 0, NULL, NULL); if (!str) return NULL; @@ -168,9 +169,9 @@ static void* clipboard_synthesize_utf8_string(wClipboard* clipboard, UINT32 form if (formatId == CF_UNICODETEXT) { - size = (INT64) * pSize; - size = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) data, - size / 2, (CHAR**) &pDstData, 0, NULL, NULL); + size_t wsize = _wcsnlen(data, (*pSize) / 2); + size = ConvertFromUnicode(CP_UTF8, 0, (LPWSTR) data, + wsize, (CHAR**) &pDstData, 0, NULL, NULL); if (!pDstData) return NULL; From 66e71ef963a18547d0c213ef5512efc6923185f2 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 10 Dec 2018 14:02:57 +0100 Subject: [PATCH 3/3] Added missing define for _wcsnlen for windows. --- winpr/include/winpr/string.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/winpr/include/winpr/string.h b/winpr/include/winpr/string.h index 166d800b6..d3cd29dc2 100644 --- a/winpr/include/winpr/string.h +++ b/winpr/include/winpr/string.h @@ -58,7 +58,7 @@ WINPR_API int _strnicmp(const char* string1, const char* string2, size_t count); WINPR_API int _wcscmp(const WCHAR* string1, const WCHAR* string2); WINPR_API size_t _wcslen(const WCHAR* str); -WINPR_API size_t _wcsnlen(const WCHAR* str, size_t numberOfElements); +WINPR_API size_t _wcsnlen(const WCHAR* str, size_t maxNumberOfElements); WINPR_API WCHAR* _wcschr(const WCHAR* str, WCHAR c); WINPR_API WCHAR* _wcsrchr(const WCHAR* str, WCHAR c); @@ -72,6 +72,7 @@ WINPR_API WCHAR* wcstok_s(WCHAR* strToken, const WCHAR* strDelimit, #define _wcscmp wcscmp #define _wcslen wcslen +#define _wcsnlen wcsnlen #define _wcschr wcschr #define _wcsrchr wcsrchr