diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 01:24:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 01:24:41 +0000 |
commit | a9bcc81f821d7c66f623779fa5147e728eb3c388 (patch) | |
tree | 98676963bcdd537ae5908a067a8eb110b93486a6 /winpr/libwinpr/path/include | |
parent | Initial commit. (diff) | |
download | freerdp3-a9bcc81f821d7c66f623779fa5147e728eb3c388.tar.xz freerdp3-a9bcc81f821d7c66f623779fa5147e728eb3c388.zip |
Adding upstream version 3.3.0+dfsg1.upstream/3.3.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'winpr/libwinpr/path/include')
-rw-r--r-- | winpr/libwinpr/path/include/PathAllocCombine.c | 180 | ||||
-rw-r--r-- | winpr/libwinpr/path/include/PathCchAddExtension.c | 101 | ||||
-rw-r--r-- | winpr/libwinpr/path/include/PathCchAddSeparator.c | 64 | ||||
-rw-r--r-- | winpr/libwinpr/path/include/PathCchAddSeparatorEx.c | 66 | ||||
-rw-r--r-- | winpr/libwinpr/path/include/PathCchAppend.c | 131 |
5 files changed, 542 insertions, 0 deletions
diff --git a/winpr/libwinpr/path/include/PathAllocCombine.c b/winpr/libwinpr/path/include/PathAllocCombine.c new file mode 100644 index 0000000..abdbd29 --- /dev/null +++ b/winpr/libwinpr/path/include/PathAllocCombine.c @@ -0,0 +1,180 @@ + +/* +#define DEFINE_UNICODE FALSE +#define CUR_PATH_SEPARATOR_CHR '\\' +#define CUR_PATH_SEPARATOR_STR "\\" +#define PATH_ALLOC_COMBINE PathAllocCombineA +*/ + +/** + * FIXME: These implementations of the PathAllocCombine functions have + * several issues: + * - pszPathIn or pszMore may be NULL (but not both) + * - no check if pszMore is fully qualified (if so, it must be directly + * copied to the output buffer without being combined with pszPathIn. + * - if pszMore begins with a _single_ backslash it must be combined with + * only the root of the path pointed to by pszPathIn and there's no code + * to extract the root of pszPathIn. + * - the function will crash with some short string lengths of the parameters + */ + +#if DEFINE_UNICODE + +HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags, + PWSTR* ppszPathOut) +{ + PWSTR pszPathOut; + BOOL backslashIn; + BOOL backslashMore; + size_t pszMoreLength; + size_t pszPathInLength; + size_t pszPathOutLength; + WLog_WARN(TAG, "has known bugs and needs fixing."); + + if (!ppszPathOut) + return E_INVALIDARG; + + if (!pszPathIn && !pszMore) + return E_INVALIDARG; + + if (!pszMore) + return E_FAIL; /* valid but not implemented, see top comment */ + + if (!pszPathIn) + return E_FAIL; /* valid but not implemented, see top comment */ + + pszPathInLength = _wcslen(pszPathIn); + pszMoreLength = _wcslen(pszMore); + + /* prevent segfaults - the complete implementation below is buggy */ + if (pszPathInLength < 3) + return E_FAIL; + + backslashIn = (pszPathIn[pszPathInLength - 1] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE; + backslashMore = (pszMore[0] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE; + + if (backslashMore) + { + if ((pszPathIn[1] == ':') && (pszPathIn[2] == CUR_PATH_SEPARATOR_CHR)) + { + const WCHAR colon[] = { ':', '\0' }; + size_t sizeOfBuffer; + pszPathOutLength = sizeof(WCHAR) + pszMoreLength; + sizeOfBuffer = (pszPathOutLength + 1) * sizeof(WCHAR); + pszPathOut = (PWSTR)calloc(sizeOfBuffer, sizeof(WCHAR)); + + if (!pszPathOut) + return E_OUTOFMEMORY; + + _wcsncat(pszPathOut, &pszPathIn[0], 1); + _wcsncat(pszPathOut, colon, ARRAYSIZE(colon)); + _wcsncat(pszPathOut, pszMore, pszMoreLength); + *ppszPathOut = pszPathOut; + return S_OK; + } + } + else + { + const WCHAR sep[] = CUR_PATH_SEPARATOR_STR; + size_t sizeOfBuffer; + pszPathOutLength = pszPathInLength + pszMoreLength; + sizeOfBuffer = (pszPathOutLength + 1) * 2; + pszPathOut = (PWSTR)calloc(sizeOfBuffer, 2); + + if (!pszPathOut) + return E_OUTOFMEMORY; + + _wcsncat(pszPathOut, pszPathIn, pszPathInLength); + if (!backslashIn) + _wcsncat(pszPathOut, sep, ARRAYSIZE(sep)); + _wcsncat(pszPathOut, pszMore, pszMoreLength); + + *ppszPathOut = pszPathOut; + return S_OK; + } + + return E_FAIL; +} + +#else + +HRESULT PATH_ALLOC_COMBINE(PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags, PSTR* ppszPathOut) +{ + PSTR pszPathOut; + BOOL backslashIn; + BOOL backslashMore; + int pszMoreLength; + int pszPathInLength; + int pszPathOutLength; + WLog_WARN(TAG, "has known bugs and needs fixing."); + + if (!ppszPathOut) + return E_INVALIDARG; + + if (!pszPathIn && !pszMore) + return E_INVALIDARG; + + if (!pszMore) + return E_FAIL; /* valid but not implemented, see top comment */ + + if (!pszPathIn) + return E_FAIL; /* valid but not implemented, see top comment */ + + pszPathInLength = strlen(pszPathIn); + pszMoreLength = strlen(pszMore); + + /* prevent segfaults - the complete implementation below is buggy */ + if (pszPathInLength < 3) + return E_FAIL; + + backslashIn = (pszPathIn[pszPathInLength - 1] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE; + backslashMore = (pszMore[0] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE; + + if (backslashMore) + { + if ((pszPathIn[1] == ':') && (pszPathIn[2] == CUR_PATH_SEPARATOR_CHR)) + { + size_t sizeOfBuffer; + pszPathOutLength = 2 + pszMoreLength; + sizeOfBuffer = (pszPathOutLength + 1) * 2; + pszPathOut = (PSTR)calloc(sizeOfBuffer, 2); + + if (!pszPathOut) + return E_OUTOFMEMORY; + + sprintf_s(pszPathOut, sizeOfBuffer, "%c:%s", pszPathIn[0], pszMore); + *ppszPathOut = pszPathOut; + return S_OK; + } + } + else + { + size_t sizeOfBuffer; + pszPathOutLength = pszPathInLength + pszMoreLength; + sizeOfBuffer = (pszPathOutLength + 1) * 2; + pszPathOut = (PSTR)calloc(sizeOfBuffer, 2); + + if (!pszPathOut) + return E_OUTOFMEMORY; + + if (backslashIn) + sprintf_s(pszPathOut, sizeOfBuffer, "%s%s", pszPathIn, pszMore); + else + sprintf_s(pszPathOut, sizeOfBuffer, "%s" CUR_PATH_SEPARATOR_STR "%s", pszPathIn, + pszMore); + + *ppszPathOut = pszPathOut; + return S_OK; + } + + return E_FAIL; +} + +#endif + +/* +#undef DEFINE_UNICODE +#undef CUR_PATH_SEPARATOR_CHR +#undef CUR_PATH_SEPARATOR_STR +#undef PATH_ALLOC_COMBINE +*/ diff --git a/winpr/libwinpr/path/include/PathCchAddExtension.c b/winpr/libwinpr/path/include/PathCchAddExtension.c new file mode 100644 index 0000000..498cfab --- /dev/null +++ b/winpr/libwinpr/path/include/PathCchAddExtension.c @@ -0,0 +1,101 @@ + +/* +#define DEFINE_UNICODE FALSE +#define CUR_PATH_SEPARATOR_CHR '\\' +#define PATH_CCH_ADD_EXTENSION PathCchAddExtensionA +*/ + +#if DEFINE_UNICODE + +HRESULT PATH_CCH_ADD_EXTENSION(PWSTR pszPath, size_t cchPath, PCWSTR pszExt) +{ + LPWSTR pDot; + BOOL bExtDot; + LPWSTR pBackslash; + size_t pszExtLength; + size_t pszPathLength; + + if (!pszPath) + return E_INVALIDARG; + + if (!pszExt) + return E_INVALIDARG; + + pszExtLength = _wcslen(pszExt); + pszPathLength = _wcslen(pszPath); + bExtDot = (pszExt[0] == '.') ? TRUE : FALSE; + + pDot = _wcsrchr(pszPath, '.'); + pBackslash = _wcsrchr(pszPath, CUR_PATH_SEPARATOR_CHR); + + if (pDot && pBackslash) + { + if (pDot > pBackslash) + return S_FALSE; + } + + if (cchPath > pszPathLength + pszExtLength + ((bExtDot) ? 0 : 1)) + { + const WCHAR dot[] = { '.', '\0' }; + WCHAR* ptr = &pszPath[pszPathLength]; + *ptr = '\0'; + + if (!bExtDot) + _wcsncat(ptr, dot, _wcslen(dot)); + _wcsncat(ptr, pszExt, pszExtLength); + + return S_OK; + } + + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); +} + +#else + +HRESULT PATH_CCH_ADD_EXTENSION(PSTR pszPath, size_t cchPath, PCSTR pszExt) +{ + CHAR* pDot; + BOOL bExtDot; + CHAR* pBackslash; + size_t pszExtLength; + size_t pszPathLength; + + if (!pszPath) + return E_INVALIDARG; + + if (!pszExt) + return E_INVALIDARG; + + pszExtLength = strlen(pszExt); + pszPathLength = strlen(pszPath); + bExtDot = (pszExt[0] == '.') ? TRUE : FALSE; + + pDot = strrchr(pszPath, '.'); + pBackslash = strrchr(pszPath, CUR_PATH_SEPARATOR_CHR); + + if (pDot && pBackslash) + { + if (pDot > pBackslash) + return S_FALSE; + } + + if (cchPath > pszPathLength + pszExtLength + ((bExtDot) ? 0 : 1)) + { + if (bExtDot) + sprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength, "%s", pszExt); + else + sprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength, ".%s", pszExt); + + return S_OK; + } + + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); +} + +#endif + +/* +#undef DEFINE_UNICODE +#undef CUR_PATH_SEPARATOR_CHR +#undef PATH_CCH_ADD_EXTENSION +*/ diff --git a/winpr/libwinpr/path/include/PathCchAddSeparator.c b/winpr/libwinpr/path/include/PathCchAddSeparator.c new file mode 100644 index 0000000..0ef391c --- /dev/null +++ b/winpr/libwinpr/path/include/PathCchAddSeparator.c @@ -0,0 +1,64 @@ + +/* +#define DEFINE_UNICODE FALSE +#define CUR_PATH_SEPARATOR_CHR '\\' +#define PATH_CCH_ADD_SEPARATOR PathCchAddBackslashA +*/ + +#if DEFINE_UNICODE + +HRESULT PATH_CCH_ADD_SEPARATOR(PWSTR pszPath, size_t cchPath) +{ + size_t pszPathLength; + + if (!pszPath) + return E_INVALIDARG; + + pszPathLength = _wcslen(pszPath); + + if (pszPath[pszPathLength - 1] == CUR_PATH_SEPARATOR_CHR) + return S_FALSE; + + if (cchPath > (pszPathLength + 1)) + { + pszPath[pszPathLength] = CUR_PATH_SEPARATOR_CHR; + pszPath[pszPathLength + 1] = '\0'; + + return S_OK; + } + + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); +} + +#else + +HRESULT PATH_CCH_ADD_SEPARATOR(PSTR pszPath, size_t cchPath) +{ + size_t pszPathLength; + + if (!pszPath) + return E_INVALIDARG; + + pszPathLength = strlen(pszPath); + + if (pszPath[pszPathLength - 1] == CUR_PATH_SEPARATOR_CHR) + return S_FALSE; + + if (cchPath > (pszPathLength + 1)) + { + pszPath[pszPathLength] = CUR_PATH_SEPARATOR_CHR; + pszPath[pszPathLength + 1] = '\0'; + + return S_OK; + } + + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); +} + +#endif + +/* +#undef DEFINE_UNICODE +#undef CUR_PATH_SEPARATOR_CHR +#undef PATH_CCH_ADD_SEPARATOR +*/ diff --git a/winpr/libwinpr/path/include/PathCchAddSeparatorEx.c b/winpr/libwinpr/path/include/PathCchAddSeparatorEx.c new file mode 100644 index 0000000..02832d8 --- /dev/null +++ b/winpr/libwinpr/path/include/PathCchAddSeparatorEx.c @@ -0,0 +1,66 @@ + +/* +#define DEFINE_UNICODE FALSE +#define CUR_PATH_SEPARATOR_CHR '\\' +#define PATH_CCH_ADD_SEPARATOR_EX PathCchAddBackslashExA +*/ + +#if DEFINE_UNICODE + +HRESULT PATH_CCH_ADD_SEPARATOR_EX(PWSTR pszPath, size_t cchPath, PWSTR* ppszEnd, + size_t* pcchRemaining) +{ + size_t pszPathLength; + + if (!pszPath) + return E_INVALIDARG; + + pszPathLength = _wcslen(pszPath); + + if (pszPath[pszPathLength - 1] == CUR_PATH_SEPARATOR_CHR) + return S_FALSE; + + if (cchPath > (pszPathLength + 1)) + { + pszPath[pszPathLength] = CUR_PATH_SEPARATOR_CHR; + pszPath[pszPathLength + 1] = '\0'; + + return S_OK; + } + + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); +} + +#else + +HRESULT PATH_CCH_ADD_SEPARATOR_EX(PSTR pszPath, size_t cchPath, PSTR* ppszEnd, + size_t* pcchRemaining) +{ + size_t pszPathLength; + + if (!pszPath) + return E_INVALIDARG; + + pszPathLength = strlen(pszPath); + + if (pszPath[pszPathLength - 1] == CUR_PATH_SEPARATOR_CHR) + return S_FALSE; + + if (cchPath > (pszPathLength + 1)) + { + pszPath[pszPathLength] = CUR_PATH_SEPARATOR_CHR; + pszPath[pszPathLength + 1] = '\0'; + + return S_OK; + } + + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); +} + +#endif + +/* +#undef DEFINE_UNICODE +#undef CUR_PATH_SEPARATOR_CHR +#undef PATH_CCH_ADD_SEPARATOR_EX +*/ diff --git a/winpr/libwinpr/path/include/PathCchAppend.c b/winpr/libwinpr/path/include/PathCchAppend.c new file mode 100644 index 0000000..a4f58cb --- /dev/null +++ b/winpr/libwinpr/path/include/PathCchAppend.c @@ -0,0 +1,131 @@ + +/* +#define DEFINE_UNICODE FALSE +#define CUR_PATH_SEPARATOR_CHR '\\' +#define CUR_PATH_SEPARATOR_STR "\\" +#define PATH_CCH_APPEND PathCchAppendA +*/ + +#if DEFINE_UNICODE + +HRESULT PATH_CCH_APPEND(PWSTR pszPath, size_t cchPath, PCWSTR pszMore) +{ + BOOL pathBackslash; + BOOL moreBackslash; + size_t pszMoreLength; + size_t pszPathLength; + + if (!pszPath) + return E_INVALIDARG; + + if (!pszMore) + return E_INVALIDARG; + + if (cchPath == 0 || cchPath > PATHCCH_MAX_CCH) + return E_INVALIDARG; + + pszMoreLength = _wcslen(pszMore); + pszPathLength = _wcslen(pszPath); + + pathBackslash = (pszPath[pszPathLength - 1] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE; + moreBackslash = (pszMore[0] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE; + + if (pathBackslash && moreBackslash) + { + if ((pszPathLength + pszMoreLength - 1) < cchPath) + { + WCHAR* ptr = &pszPath[pszPathLength]; + *ptr = '\0'; + _wcsncat(ptr, &pszMore[1], _wcslen(&pszMore[1])); + return S_OK; + } + } + else if ((pathBackslash && !moreBackslash) || (!pathBackslash && moreBackslash)) + { + if ((pszPathLength + pszMoreLength) < cchPath) + { + WCHAR* ptr = &pszPath[pszPathLength]; + *ptr = '\0'; + _wcsncat(ptr, pszMore, _wcslen(pszMore)); + return S_OK; + } + } + else if (!pathBackslash && !moreBackslash) + { + if ((pszPathLength + pszMoreLength + 1) < cchPath) + { + const WCHAR sep[] = CUR_PATH_SEPARATOR_STR; + WCHAR* ptr = &pszPath[pszPathLength]; + *ptr = '\0'; + _wcsncat(ptr, sep, _wcslen(sep)); + _wcsncat(ptr, pszMore, _wcslen(pszMore)); + return S_OK; + } + } + + return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE); +} + +#else + +HRESULT PATH_CCH_APPEND(PSTR pszPath, size_t cchPath, PCSTR pszMore) +{ + BOOL pathBackslash = FALSE; + BOOL moreBackslash = FALSE; + size_t pszMoreLength; + size_t pszPathLength; + + if (!pszPath) + return E_INVALIDARG; + + if (!pszMore) + return E_INVALIDARG; + + if (cchPath == 0 || cchPath > PATHCCH_MAX_CCH) + return E_INVALIDARG; + + pszPathLength = strlen(pszPath); + if (pszPathLength > 0) + pathBackslash = (pszPath[pszPathLength - 1] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE; + + pszMoreLength = strlen(pszMore); + if (pszMoreLength > 0) + moreBackslash = (pszMore[0] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE; + + if (pathBackslash && moreBackslash) + { + if ((pszPathLength + pszMoreLength - 1) < cchPath) + { + sprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength, "%s", &pszMore[1]); + return S_OK; + } + } + else if ((pathBackslash && !moreBackslash) || (!pathBackslash && moreBackslash)) + { + if ((pszPathLength + pszMoreLength) < cchPath) + { + sprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength, "%s", pszMore); + return S_OK; + } + } + else if (!pathBackslash && !moreBackslash) + { + if ((pszPathLength + pszMoreLength + 1) < cchPath) + { + sprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength, CUR_PATH_SEPARATOR_STR "%s", + pszMore); + return S_OK; + } + } + + return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE); +} + +#endif + +/* +#undef DEFINE_UNICODE +#undef CUR_PATH_SEPARATOR_CHR +#undef CUR_PATH_SEPARATOR_STR +#undef PATH_CCH_APPEND +*/ |