aboutsummaryrefslogtreecommitdiff
path: root/src/libs/dutil/WixToolset.DUtil/strutil.cpp
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2026-01-21 00:16:24 -0800
committerRob Mensching <rob@firegiant.com>2026-01-21 12:34:07 -0800
commit50de1c4ee7a56e47a06c44769cea5aa2457a829b (patch)
tree26657b5655b97add06c7980e4ae1ce30d6e8a401 /src/libs/dutil/WixToolset.DUtil/strutil.cpp
parent49fbdf6f34b69a0157addcda2e28a96227a72630 (diff)
downloadwix-50de1c4ee7a56e47a06c44769cea5aa2457a829b.tar.gz
wix-50de1c4ee7a56e47a06c44769cea5aa2457a829b.tar.bz2
wix-50de1c4ee7a56e47a06c44769cea5aa2457a829b.zip
Improve handling of nulls in MultiSzInsertString and MultiSzLen
Resolves 7311
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/strutil.cpp')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/strutil.cpp31
1 files changed, 23 insertions, 8 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/strutil.cpp b/src/libs/dutil/WixToolset.DUtil/strutil.cpp
index 0a00c690..013c1b12 100644
--- a/src/libs/dutil/WixToolset.DUtil/strutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/strutil.cpp
@@ -1872,9 +1872,14 @@ NOTE: returns 0 if the multisz in not properly terminated with two nulls
1872extern "C" HRESULT DAPI MultiSzLen( 1872extern "C" HRESULT DAPI MultiSzLen(
1873 __in_ecount(*pcch) __nullnullterminated LPCWSTR pwzMultiSz, 1873 __in_ecount(*pcch) __nullnullterminated LPCWSTR pwzMultiSz,
1874 __out SIZE_T* pcch 1874 __out SIZE_T* pcch
1875) 1875 )
1876{ 1876{
1877 Assert(pcch); 1877 Assert(pcch);
1878 if (!pwzMultiSz)
1879 {
1880 *pcch = 0;
1881 return S_OK;
1882 }
1878 1883
1879 HRESULT hr = S_OK; 1884 HRESULT hr = S_OK;
1880 LPCWSTR wz = pwzMultiSz; 1885 LPCWSTR wz = pwzMultiSz;
@@ -1941,10 +1946,10 @@ extern "C" HRESULT DAPI MultiSzPrepend(
1941 hr = ::StringCchLengthW(pwzInsert, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchInsert)); 1946 hr = ::StringCchLengthW(pwzInsert, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchInsert));
1942 StrExitOnRootFailure(hr, "failed to get length of insert string"); 1947 StrExitOnRootFailure(hr, "failed to get length of insert string");
1943 1948
1944 cchResult = cchInsert + cchMultiSz + 1; 1949 cchResult = cchInsert + (cchMultiSz ? cchMultiSz : 1) + 1;
1945 1950
1946 // Allocate the result buffer 1951 // Allocate the result buffer
1947 hr = StrAlloc(&pwzResult, cchResult + 1); 1952 hr = StrAlloc(&pwzResult, cchResult);
1948 StrExitOnFailure(hr, "failed to allocate result string"); 1953 StrExitOnFailure(hr, "failed to allocate result string");
1949 1954
1950 // Prepend 1955 // Prepend
@@ -1954,8 +1959,7 @@ extern "C" HRESULT DAPI MultiSzPrepend(
1954 // If there was no MULTISZ, double null terminate our result, otherwise, copy the MULTISZ in 1959 // If there was no MULTISZ, double null terminate our result, otherwise, copy the MULTISZ in
1955 if (0 == cchMultiSz) 1960 if (0 == cchMultiSz)
1956 { 1961 {
1957 pwzResult[cchResult] = L'\0'; 1962 pwzResult[cchResult - 2] = L'\0';
1958 ++cchResult;
1959 } 1963 }
1960 else 1964 else
1961 { 1965 {
@@ -1967,6 +1971,7 @@ extern "C" HRESULT DAPI MultiSzPrepend(
1967 } 1971 }
1968 1972
1969 // Set the result 1973 // Set the result
1974 pwzResult[cchResult - 1] = L'\0';
1970 *ppwzMultiSz = pwzResult; 1975 *ppwzMultiSz = pwzResult;
1971 1976
1972 if (pcchMultiSz) 1977 if (pcchMultiSz)
@@ -2257,19 +2262,29 @@ extern "C" HRESULT DAPI MultiSzInsertString(
2257 // 2262 //
2258 // Insert the string 2263 // Insert the string
2259 // 2264 //
2260 cchResult = cchMultiSz + cchString + 1; 2265 cchResult = (cchMultiSz ? cchMultiSz : 1) + cchString + 1;
2261 2266
2262 hr = StrAlloc(&pwzResult, cchResult); 2267 hr = StrAlloc(&pwzResult, cchResult);
2263 StrExitOnFailure(hr, "failed to allocate result string for MULTISZ insert"); 2268 StrExitOnFailure(hr, "failed to allocate result string for MULTISZ insert");
2264 2269
2265 // Copy the part before the insert 2270 // Copy the part before the insert
2266 ::CopyMemory(pwzResult, *ppwzMultiSz, cchProgress * sizeof(WCHAR)); 2271 if (cchProgress)
2272 {
2273 ::CopyMemory(pwzResult, *ppwzMultiSz, cchProgress * sizeof(WCHAR));
2274 }
2267 2275
2268 // Copy the insert part 2276 // Copy the insert part
2269 ::CopyMemory(pwzResult + cchProgress, pwzInsert, (cchString + 1) * sizeof(WCHAR)); 2277 ::CopyMemory(pwzResult + cchProgress, pwzInsert, (cchString + 1) * sizeof(WCHAR));
2270 2278
2271 // Copy the part after the insert 2279 // Copy the part after the insert
2272 ::CopyMemory(pwzResult + cchProgress + cchString + 1, wz, (cchMultiSz - cchProgress) * sizeof(WCHAR)); 2280 if (cchMultiSz > cchProgress)
2281 {
2282 ::CopyMemory(pwzResult + cchProgress + cchString + 1, wz, (cchMultiSz - cchProgress) * sizeof(WCHAR));
2283 }
2284
2285 // Ensure double-null termination
2286 pwzResult[cchResult - 1] = L'\0';
2287 pwzResult[cchResult - 2] = L'\0';
2273 2288
2274 // Free the old buffer 2289 // Free the old buffer
2275 ReleaseNullStr(*ppwzMultiSz); 2290 ReleaseNullStr(*ppwzMultiSz);