Skip to content

Commit 2ade6f8

Browse files
authored
Linux: Implement prefix-counted BSTR allocation in SysAllocStringLen (#3250)
While this prefix may be an implementation detail the BSTR type guarantees to be able to store NULL values without accidentally truncating the string, hence its length must be available to replace the usual NULL terminator. This string length in bytes is stored in the four bytes preceding a BSTR pointer [1], whose value can be retrieved using SysStringLen. This commit implements the type in the same way in WinAdapter such that users of the functions returning a BSTR (currently only in dxcisense) can expect and use the type in the same way on Linux as they would on Windows. While this function and type currently only seem to be involved in names and logging where NULLs are unlikely, it is good practice to mirror the Windows type exactly for future-proofing. Besides, SysAllocStringLen does not specify anything about taking ownership of strIn so the realloc here is wrong either way. [1]: https://docs.microsoft.com/en-us/previous-versions/windows/desktop/automat/bstr
1 parent a39e52d commit 2ade6f8

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

include/dxc/Support/WinAdapter.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@
4545
#define CoTaskMemAlloc malloc
4646
#define CoTaskMemFree free
4747

48-
#define SysFreeString free
49-
#define SysAllocStringLen(ptr, size) \
50-
(wchar_t *)realloc(ptr, (size + 1) * sizeof(wchar_t))
51-
5248
#define ARRAYSIZE(array) (sizeof(array) / sizeof(array[0]))
5349

5450
#define _countof(a) (sizeof(a) / sizeof(*(a)))
@@ -916,6 +912,12 @@ class CHeapPtr : public CHeapPtrBase<T, Allocator> {
916912

917913
#define CComHeapPtr CHeapPtr
918914

915+
//===--------------------------- BSTR Allocation --------------------------===//
916+
917+
void SysFreeString(BSTR bstrString);
918+
// Allocate string with length prefix
919+
BSTR SysAllocStringLen(const OLECHAR *strIn, UINT ui);
920+
919921
//===--------------------- UTF-8 Related Types ----------------------------===//
920922

921923
// Code Page

lib/DxcSupport/WinAdapter.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,36 @@ void *CAllocator::Reallocate(void *p, size_t nBytes) throw() {
6868
void *CAllocator::Allocate(size_t nBytes) throw() { return malloc(nBytes); }
6969
void CAllocator::Free(void *p) throw() { free(p); }
7070

71+
//===--------------------------- BSTR Allocation --------------------------===//
72+
73+
void SysFreeString(BSTR bstrString) {
74+
if (bstrString)
75+
free((void *)((uintptr_t)bstrString - sizeof(uint32_t)));
76+
}
77+
78+
// Allocate string with length prefix
79+
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/automat/bstr
80+
BSTR SysAllocStringLen(const OLECHAR *strIn, UINT ui) {
81+
uint32_t *blobOut =
82+
(uint32_t *)malloc(sizeof(uint32_t) + (ui + 1) * sizeof(OLECHAR));
83+
84+
if (!blobOut)
85+
return nullptr;
86+
87+
// Size in bytes without trailing NULL character
88+
blobOut[0] = ui * sizeof(OLECHAR);
89+
90+
BSTR strOut = (BSTR)&blobOut[1];
91+
92+
if (strIn)
93+
memcpy(strOut, strIn, blobOut[0]);
94+
95+
// Write trailing NULL character:
96+
strOut[ui] = 0;
97+
98+
return strOut;
99+
}
100+
71101
//===---------------------- Char converstion ------------------------------===//
72102

73103
const char *CPToLocale(uint32_t CodePage) {

0 commit comments

Comments
 (0)