@joebigelow / wix-1 / commits / 0f993110

Add MemSizeChecked.

Sean Hall committed May 26, 2022 at 17:32 UTC 0f9931107ecf9e1f6714e6fd2cabc76d2ddb1153
8 files changed +130 -109
src/libs/dutil/WixToolset.DUtil/buffutil.cpp
+5 -1
@@ -508,10 +508,14 @@ static HRESULT EnsureBufferSize(
508 {
509 HRESULT hr = S_OK;
510 SIZE_T cbTarget = ((cbSize / BUFFER_INCREMENT) + 1) * BUFFER_INCREMENT;
511 + SIZE_T cbCurrent = 0;
512
513 if (*ppbBuffer)
514 {
514 - if (MemSize(*ppbBuffer) < cbTarget)
515 + hr = MemSizeChecked(*ppbBuffer, &cbCurrent);
516 + BuffExitOnFailure(hr, "Failed to get current buffer size.");
517 +
518 + if (cbCurrent < cbTarget)
519 {
520 LPVOID pv = MemReAlloc(*ppbBuffer, cbTarget, TRUE);
521 BuffExitOnNull(pv, hr, E_OUTOFMEMORY, "Failed to reallocate buffer.");
src/libs/dutil/WixToolset.DUtil/inc/memutil.h
+4
@@ -80,6 +80,10 @@ HRESULT DAPI MemFree(
80 SIZE_T DAPI MemSize(
81 __in LPCVOID pv
82 );
83 +HRESULT DAPI MemSizeChecked(
84 + __in LPCVOID pv,
85 + __out SIZE_T* pcb
86 + );
87
88 #ifdef __cplusplus
89 }
src/libs/dutil/WixToolset.DUtil/inc/strutil.h
+6 -2
@@ -139,11 +139,15 @@ HRESULT DAPI StrAllocFromError(
139
140 HRESULT DAPI StrMaxLength(
141 __in LPCVOID p,
142 - __out SIZE_T* pcbch
142 + __out SIZE_T* pcch
143 + );
144 +HRESULT DAPI StrMaxLengthAnsi(
145 + __in LPCVOID p,
146 + __out SIZE_T* pcch
147 );
148 HRESULT DAPI StrSize(
149 __in LPCVOID p,
146 - __out SIZE_T* pcbb
150 + __out SIZE_T* pcb
151 );
152
153 HRESULT DAPI StrFree(
src/libs/dutil/WixToolset.DUtil/memutil.cpp
+39 -12
@@ -9,6 +9,7 @@
9 #define MemExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_MEMUTIL, x, s, __VA_ARGS__)
10 #define MemExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_MEMUTIL, x, s, __VA_ARGS__)
11 #define MemExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_MEMUTIL, x, s, __VA_ARGS__)
12 +#define MemExitWithRootFailure(x, e, s, ...) ExitWithRootFailureSource(DUTIL_SOURCE_MEMUTIL, x, e, s, __VA_ARGS__)
13 #define MemExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_MEMUTIL, x, s, __VA_ARGS__)
14 #define MemExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_MEMUTIL, p, x, e, s, __VA_ARGS__)
15 #define MemExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_MEMUTIL, p, x, s, __VA_ARGS__)
@@ -74,6 +75,7 @@ extern "C" HRESULT DAPI MemReAllocSecure(
75 HRESULT hr = S_OK;
76 DWORD dwFlags = HEAP_REALLOC_IN_PLACE_ONLY;
77 LPVOID pvNew = NULL;
78 + SIZE_T cb = 0;
79
80 dwFlags |= fZero ? HEAP_ZERO_MEMORY : 0;
81 pvNew = ::HeapReAlloc(::GetProcessHeap(), dwFlags, pv, cbSize);
@@ -82,18 +84,16 @@ extern "C" HRESULT DAPI MemReAllocSecure(
84 pvNew = MemAlloc(cbSize, fZero);
85 if (pvNew)
86 {
85 - const SIZE_T cbCurrent = MemSize(pv);
86 - if (-1 == cbCurrent)
87 - {
88 - MemExitOnRootFailure(hr = E_INVALIDARG, "Failed to get memory size");
89 - }
87 + hr = MemSizeChecked(pv, &cb);
88 + MemExitOnFailure(hr, "Failed to get current memory size.");
89 +
90 + const SIZE_T cbCurrent = cb;
91
92 // HeapReAlloc may allocate more memory than requested.
92 - const SIZE_T cbNew = MemSize(pvNew);
93 - if (-1 == cbNew)
94 - {
95 - MemExitOnRootFailure(hr = E_INVALIDARG, "Failed to get memory size");
96 - }
93 + hr = MemSizeChecked(pvNew, &cb);
94 + MemExitOnFailure(hr, "Failed to get new memory size.");
95 +
96 + const SIZE_T cbNew = cb;
97
98 cbSize = cbNew;
99 if (cbSize > cbCurrent)
@@ -149,7 +149,10 @@ extern "C" HRESULT DAPI MemReAllocArray(
149
150 if (*ppvArray)
151 {
152 - SIZE_T cbCurrent = MemSize(*ppvArray);
152 + SIZE_T cbCurrent = 0;
153 + hr = MemSizeChecked(*ppvArray, &cbCurrent);
154 + MemExitOnFailure(hr, "Failed to get current memory size.");
155 +
156 if (cbCurrent < cbNew)
157 {
158 pvNew = MemReAlloc(*ppvArray, cbNew, TRUE);
@@ -192,7 +195,11 @@ extern "C" HRESULT DAPI MemEnsureArraySize(
195 if (*ppvArray)
196 {
197 SIZE_T cbUsed = cArray * cbArrayType;
195 - SIZE_T cbCurrent = MemSize(*ppvArray);
198 + SIZE_T cbCurrent = 0;
199 +
200 + hr = MemSizeChecked(*ppvArray, &cbCurrent);
201 + MemExitOnFailure(hr, "Failed to get current memory size.");
202 +
203 if (cbCurrent < cbUsed)
204 {
205 pvNew = MemReAlloc(*ppvArray, cbNew, TRUE);
@@ -355,3 +362,23 @@ extern "C" SIZE_T DAPI MemSize(
362 // AssertSz(vfMemInitialized, "MemInitialize() not called, this would normally crash");
363 return ::HeapSize(::GetProcessHeap(), 0, pv);
364 }
365 +
366 +
367 +extern "C" HRESULT DAPI MemSizeChecked(
368 + __in LPCVOID pv,
369 + __out SIZE_T* pcb
370 + )
371 +{
372 + HRESULT hr = S_OK;
373 +
374 +// AssertSz(vfMemInitialized, "MemInitialize() not called, this would normally crash");
375 + *pcb = MemSize(pv);
376 +
377 + if (-1 == *pcb)
378 + {
379 + MemExitWithRootFailure(hr, E_INVALIDARG, "Failed to get memory size");
380 + }
381 +
382 +LExit:
383 + return hr;
384 +}
src/libs/dutil/WixToolset.DUtil/metautil.cpp
+4 -1
@@ -300,7 +300,10 @@ extern "C" HRESULT DAPI MetaGetValue(
300 }
301 else // set the size of the data to the actual size of the memory
302 {
303 - SIZE_T cb = MemSize(pmr->pbMDData);
303 + SIZE_T cb = 0;
304 + hr = MemSizeChecked(pmr->pbMDData, &cb);
305 + MetaExitOnFailure(hr, "failed to get metabase size");
306 +
307 if (cb > DWORD_MAX)
308 {
309 MetaExitOnRootFailure(hr = E_INVALIDSTATE, "metabase data is too large: %Iu", cb);
src/libs/dutil/WixToolset.DUtil/strutil.cpp
+58 -87
@@ -390,13 +390,8 @@ static HRESULT AllocStringHelper(
390
391 if (*ppwz)
392 {
393 - cch = MemSize(*ppwz); // get the count in bytes so we can check if it failed (returns -1)
394 - if (-1 == cch)
395 - {
396 - hr = E_INVALIDARG;
397 - StrExitOnFailure(hr, "failed to get size of destination string");
398 - }
399 - cch /= sizeof(WCHAR); //convert the count in bytes to count in characters
393 + hr = StrMaxLength(*ppwz, &cch);
394 + StrExitOnFailure(hr, "failed to get size of destination string");
395 }
396
397 if (0 == cchSource && wzSource)
@@ -447,13 +442,8 @@ extern "C" HRESULT DAPI StrAnsiAllocString(
442
443 if (*ppsz)
444 {
450 - cch = MemSize(*ppsz); // get the count in bytes so we can check if it failed (returns -1)
451 - if (-1 == cch)
452 - {
453 - hr = E_INVALIDARG;
454 - StrExitOnFailure(hr, "failed to get size of destination string");
455 - }
456 - cch /= sizeof(CHAR); //convert the count in bytes to count in characters
445 + hr = StrMaxLengthAnsi(*ppsz, &cch);
446 + StrExitOnFailure(hr, "failed to get size of destination string");
447 }
448
449 if (0 == cchSource)
@@ -527,13 +517,8 @@ extern "C" HRESULT DAPI StrAllocStringAnsi(
517
518 if (*ppwz)
519 {
530 - cch = MemSize(*ppwz); // get the count in bytes so we can check if it failed (returns -1)
531 - if (-1 == cch)
532 - {
533 - hr = E_INVALIDARG;
534 - StrExitOnFailure(hr, "failed to get size of destination string");
535 - }
536 - cch /= sizeof(WCHAR); //convert the count in bytes to count in characters
520 + hr = StrMaxLength(*ppwz, &cch);
521 + StrExitOnFailure(hr, "failed to get size of destination string");
522 }
523
524 if (0 == cchSource)
@@ -605,13 +590,8 @@ HRESULT DAPI StrAnsiAllocStringAnsi(
590
591 if (*ppsz)
592 {
608 - cch = MemSize(*ppsz); // get the count in bytes so we can check if it failed (returns -1)
609 - if (-1 == cch)
610 - {
611 - hr = E_INVALIDARG;
612 - StrExitOnRootFailure(hr, "failed to get size of destination string");
613 - }
614 - cch /= sizeof(CHAR); //convert the count in bytes to count in characters
593 + hr = StrMaxLengthAnsi(*ppsz, &cch);
594 + StrExitOnRootFailure(hr, "failed to get size of destination string");
595 }
596
597 if (0 == cchSource && szSource)
@@ -664,13 +644,8 @@ extern "C" HRESULT DAPI StrAllocPrefix(
644
645 if (*ppwz)
646 {
667 - cch = MemSize(*ppwz); // get the count in bytes so we can check if it failed (returns -1)
668 - if (-1 == cch)
669 - {
670 - hr = E_INVALIDARG;
671 - StrExitOnFailure(hr, "failed to get size of destination string");
672 - }
673 - cch /= sizeof(WCHAR); //convert the count in bytes to count in characters
647 + hr = StrMaxLength(*ppwz, &cch);
648 + StrExitOnFailure(hr, "failed to get size of destination string");
649
650 hr = ::StringCchLengthW(*ppwz, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchLen));
651 StrExitOnFailure(hr, "Failed to calculate length of string");
@@ -770,13 +745,8 @@ static HRESULT AllocConcatHelper(
745
746 if (*ppwz)
747 {
773 - cch = MemSize(*ppwz); // get the count in bytes so we can check if it failed (returns -1)
774 - if (-1 == cch)
775 - {
776 - hr = E_INVALIDARG;
777 - StrExitOnFailure(hr, "failed to get size of destination string");
778 - }
779 - cch /= sizeof(WCHAR); //convert the count in bytes to count in characters
748 + hr = StrMaxLength(*ppwz, &cch);
749 + StrExitOnFailure(hr, "failed to get size of destination string");
750
751 hr = ::StringCchLengthW(*ppwz, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchLen));
752 StrExitOnFailure(hr, "Failed to calculate length of string");
@@ -833,13 +803,8 @@ extern "C" HRESULT DAPI StrAnsiAllocConcat(
803
804 if (*ppz)
805 {
836 - cch = MemSize(*ppz); // get the count in bytes so we can check if it failed (returns -1)
837 - if (-1 == cch)
838 - {
839 - hr = E_INVALIDARG;
840 - StrExitOnFailure(hr, "failed to get size of destination string");
841 - }
842 - cch /= sizeof(CHAR); // convert the count in bytes to count in characters
806 + hr = StrMaxLengthAnsi(*ppz, &cch);
807 + StrExitOnFailure(hr, "failed to get size of destination string");
808
809 #pragma prefast(push)
810 #pragma prefast(disable:25068)
@@ -1085,12 +1050,8 @@ static HRESULT AllocFormattedArgsHelper(
1050
1051 if (*ppwz)
1052 {
1088 - cbOriginal = MemSize(*ppwz); // get the count in bytes so we can check if it failed (returns -1)
1089 - if (-1 == cbOriginal)
1090 - {
1091 - hr = E_INVALIDARG;
1092 - StrExitOnRootFailure(hr, "failed to get size of destination string");
1093 - }
1053 + hr = StrSize(*ppwz, &cbOriginal);
1054 + StrExitOnFailure(hr, "failed to get size of destination string");
1055
1056 cch = cbOriginal / sizeof(WCHAR); //convert the count in bytes to count in characters
1057
@@ -1161,19 +1122,14 @@ extern "C" HRESULT DAPI StrAnsiAllocFormattedArgs(
1122 Assert(ppsz && szFormat && *szFormat);
1123
1124 HRESULT hr = S_OK;
1164 - SIZE_T cch = *ppsz ? MemSize(*ppsz) / sizeof(CHAR) : 0;
1125 + SIZE_T cch = 0;
1126 LPSTR pszOriginal = NULL;
1127 size_t cchOriginal = 0;
1128
1129 if (*ppsz)
1130 {
1170 - cch = MemSize(*ppsz); // get the count in bytes so we can check if it failed (returns -1)
1171 - if (-1 == cch)
1172 - {
1173 - hr = E_INVALIDARG;
1174 - StrExitOnRootFailure(hr, "failed to get size of destination string");
1175 - }
1176 - cch /= sizeof(CHAR); //convert the count in bytes to count in characters
1131 + hr = StrMaxLengthAnsi(*ppsz, &cch);
1132 + StrExitOnFailure(hr, "failed to get size of destination string");
1133
1134 hr = ::StringCchLengthA(*ppsz, STRSAFE_MAX_CCH, &cchOriginal);
1135 StrExitOnRootFailure(hr, "failed to get length of original string");
@@ -1280,11 +1236,8 @@ extern "C" HRESULT DAPI StrMaxLength(
1236
1237 if (p)
1238 {
1283 - *pcch = MemSize(p); // get size of entire buffer
1284 - if (-1 == *pcch)
1285 - {
1286 - ExitFunction1(hr = E_FAIL);
1287 - }
1239 + hr = StrSize(p, pcch);
1240 + StrExitOnFailure(hr, "Failed to get size of string buffer.");
1241
1242 *pcch /= sizeof(WCHAR); // reduce to count of characters
1243 }
@@ -1300,27 +1253,51 @@ LExit:
1253
1254
1255 /********************************************************************
1303 -StrSize - returns count of bytes in dynamic string p
1256 +StrMaxLengthAnsi - returns maximum number of characters that can be stored in dynamic string p
1257
1258 +NOTE: assumes non-Unicode string
1259 ********************************************************************/
1306 -extern "C" HRESULT DAPI StrSize(
1260 +extern "C" HRESULT DAPI StrMaxLengthAnsi(
1261 __in LPCVOID p,
1308 - __out SIZE_T* pcb
1262 + __out SIZE_T* pcch
1263 )
1264 {
1311 - Assert(p && pcb);
1265 + Assert(pcch);
1266
1267 HRESULT hr = S_OK;
1268
1315 - *pcb = MemSize(p);
1316 - if (-1 == *pcb)
1269 + if (p)
1270 + {
1271 + hr = StrSize(p, pcch);
1272 + StrExitOnFailure(hr, "Failed to get size of string buffer.");
1273 +
1274 + *pcch /= sizeof(CHAR); // reduce to count of characters
1275 + }
1276 + else
1277 {
1318 - hr = E_FAIL;
1278 + *pcch = 0;
1279 }
1280 + Assert(S_OK == hr);
1281
1282 +LExit:
1283 return hr;
1284 }
1285
1286 +
1287 +/********************************************************************
1288 +StrSize - returns count of bytes in dynamic string p
1289 +
1290 +********************************************************************/
1291 +extern "C" HRESULT DAPI StrSize(
1292 + __in LPCVOID p,
1293 + __out SIZE_T* pcb
1294 + )
1295 +{
1296 + Assert(p && pcb);
1297 +
1298 + return MemSizeChecked(p, pcb);
1299 +}
1300 +
1301 /********************************************************************
1302 StrFree - releases dynamic string memory allocated by any StrAlloc*() functions
1303
@@ -2786,22 +2763,16 @@ extern "C" DAPI_(HRESULT) StrSecureZeroString(
2763 )
2764 {
2765 HRESULT hr = S_OK;
2789 - SIZE_T cch;
2766 + SIZE_T cb = 0;
2767
2768 if (pwz)
2769 {
2793 - cch = MemSize(pwz);
2794 - if (-1 == cch)
2795 - {
2796 - hr = E_INVALIDARG;
2797 - StrExitOnFailure(hr, "Failed to get size of string");
2798 - }
2799 - else
2800 - {
2801 - SecureZeroMemory(pwz, cch);
2802 - }
2770 + hr = StrSize(pwz, &cb);
2771 + StrExitOnFailure(hr, "Failed to get size of string");
2772 +
2773 + SecureZeroMemory(pwz, cb);
2774 }
2804 -
2775 +
2776 LExit:
2777 return hr;
2778 }
src/libs/dutil/WixToolset.DUtil/thmutil.cpp
+8 -3
@@ -1189,6 +1189,7 @@ DAPI_(HRESULT) ThemeShowPageEx(
1189 BOOL fSaveEditboxes = FALSE;
1190 THEME_SAVEDVARIABLE* pSavedVariable = NULL;
1191 THEME_PAGE* pPage = ThemeGetPage(pTheme, dwPage);
1192 + SIZE_T cb = 0;
1193
1194 if (pPage)
1195 {
@@ -1219,9 +1220,9 @@ DAPI_(HRESULT) ThemeShowPageEx(
1220 if (THEME_SHOW_PAGE_REASON_REFRESH != reason)
1221 {
1222 pPage->cSavedVariables = 0;
1222 - if (pPage->rgSavedVariables)
1223 + if (pPage->rgSavedVariables && SUCCEEDED(MemSizeChecked(pPage->rgSavedVariables, &cb)))
1224 {
1224 - SecureZeroMemory(pPage->rgSavedVariables, MemSize(pPage->rgSavedVariables));
1225 + SecureZeroMemory(pPage->rgSavedVariables, cb);
1226 }
1227 }
1228
@@ -1238,7 +1239,11 @@ DAPI_(HRESULT) ThemeShowPageEx(
1239 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pPage->rgSavedVariables), pPage->cControlIndices, sizeof(THEME_SAVEDVARIABLE), pPage->cControlIndices);
1240 ThmExitOnFailure(hr, "Failed to allocate memory for saved variables.");
1241
1241 - SecureZeroMemory(pPage->rgSavedVariables, MemSize(pPage->rgSavedVariables));
1242 + if (SUCCEEDED(MemSizeChecked(pPage->rgSavedVariables, &cb)))
1243 + {
1244 + SecureZeroMemory(pPage->rgSavedVariables, cb);
1245 + }
1246 +
1247 pPage->cSavedVariables = pPage->cControlIndices;
1248
1249 // Save the variables in the loop below.
src/libs/dutil/test/DUtilUnitTest/MemUtilTest.cpp
+6 -3
@@ -23,7 +23,7 @@ namespace DutilTests
23 void MemUtilAppendTest()
24 {
25 HRESULT hr = S_OK;
26 - DWORD dwSize;
26 + SIZE_T cbSize = 0;
27 ArrayValue *rgValues = NULL;
28 DWORD cValues = 0;
29
@@ -65,8 +65,11 @@ namespace DutilTests
65 // and make sure it doesn't grow since we already have enough space
66 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues, sizeof(ArrayValue), 5);
67 NativeAssert::Succeeded(hr, "Failed to ensure array size matches what it should already be");
68 - dwSize = MemSize(rgValues);
69 - if (dwSize != 6 * sizeof(ArrayValue))
68 +
69 + hr = MemSizeChecked(rgValues, &cbSize);
70 + NativeAssert::Succeeded(hr, "Failed to get current array size");
71 +
72 + if (cbSize != 6 * sizeof(ArrayValue))
73 {
74 hr = E_FAIL;
75 ExitOnFailure(hr, "MemEnsureArraySize is growing an array that is already big enough!");