Andrew Nguyen : dxdiagn: Fix string copy behavior with an excessively short buffer in IDxDiagContainer ::EnumChildContainerNames.
Alexandre Julliard
julliard at winehq.org
Mon Mar 15 12:19:40 CDT 2010
Module: wine
Branch: master
Commit: fa9af5b68aaf5c3498898cb5558d548657a2367b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=fa9af5b68aaf5c3498898cb5558d548657a2367b
Author: Andrew Nguyen <arethusa26 at gmail.com>
Date: Sun Mar 14 16:36:30 2010 -0600
dxdiagn: Fix string copy behavior with an excessively short buffer in IDxDiagContainer::EnumChildContainerNames.
---
dlls/dxdiagn/container.c | 10 +++---
dlls/dxdiagn/tests/container.c | 72 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 77 insertions(+), 5 deletions(-)
diff --git a/dlls/dxdiagn/container.c b/dlls/dxdiagn/container.c
index e2b3af1..d1c023f 100644
--- a/dlls/dxdiagn/container.c
+++ b/dlls/dxdiagn/container.c
@@ -97,17 +97,17 @@ static HRESULT WINAPI IDxDiagContainerImpl_EnumChildContainerNames(PDXDIAGCONTAI
p = This->subContainers;
while (NULL != p) {
- if (dwIndex == i) {
- if (cchContainer <= strlenW(p->contName)) {
- return DXDIAG_E_INSUFFICIENT_BUFFER;
- }
+ if (dwIndex == i) {
+ TRACE("Found container name %s, copying string\n", debugstr_w(p->contName));
lstrcpynW(pwszContainer, p->contName, cchContainer);
- return S_OK;
+ return (cchContainer <= strlenW(p->contName)) ?
+ DXDIAG_E_INSUFFICIENT_BUFFER : S_OK;
}
p = p->next;
++i;
}
+ TRACE("Failed to find container name at specified index\n");
*pwszContainer = '\0';
return E_INVALIDARG;
}
diff --git a/dlls/dxdiagn/tests/container.c b/dlls/dxdiagn/tests/container.c
index 9ca464b..6fbb085 100644
--- a/dlls/dxdiagn/tests/container.c
+++ b/dlls/dxdiagn/tests/container.c
@@ -103,6 +103,7 @@ static void test_EnumChildContainerNames(void)
{
HRESULT hr;
WCHAR container[256];
+ DWORD maxcount, index;
static const WCHAR testW[] = {'t','e','s','t',0};
static const WCHAR zerotestW[] = {0,'e','s','t',0};
@@ -143,6 +144,77 @@ static void test_EnumChildContainerNames(void)
ok(!memcmp(container, zerotestW, sizeof(zerotestW)),
"Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container));
+ hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &maxcount);
+ ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr);
+ if (FAILED(hr))
+ {
+ skip("IDxDiagContainer::GetNumberOfChildContainers failed\n");
+ goto cleanup;
+ }
+
+ trace("Starting child container enumeration of the root container:\n");
+
+ /* We should be able to enumerate as many child containers as the value
+ * that IDxDiagContainer::GetNumberOfChildContainers returns. */
+ for (index = 0; index <= maxcount; index++)
+ {
+ /* A buffer size of 1 is unlikely to be valid, as only a null terminator
+ * could be stored, and it is unlikely that a container name could be empty. */
+ DWORD buffersize = 1;
+ memcpy(container, testW, sizeof(testW));
+ hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, buffersize);
+ if (hr == E_INVALIDARG)
+ {
+ /* We should get here when index is one more than the maximum index value. */
+ ok(maxcount == index,
+ "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG "
+ "on the last index %d, got 0x%08x\n", index, hr);
+ ok(container[0] == '\0',
+ "Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container));
+ break;
+ }
+ else if (hr == DXDIAG_E_INSUFFICIENT_BUFFER)
+ {
+ WCHAR temp[256];
+
+ ok(container[0] == '\0',
+ "Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container));
+
+ /* Get the container name to compare against. */
+ hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, temp, sizeof(temp)/sizeof(WCHAR));
+ ok(hr == S_OK,
+ "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr);
+
+ /* Show that the DirectX SDK's stipulation that the buffer be at
+ * least 256 characters long is a mere suggestion, and smaller sizes
+ * can be acceptable also. IDxDiagContainer::EnumChildContainerNames
+ * doesn't provide a way of getting the exact size required, so the
+ * buffersize value will be iterated to at most 256 characters. */
+ for (buffersize = 2; buffersize <= 256; buffersize++)
+ {
+ memcpy(container, testW, sizeof(testW));
+ hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, buffersize);
+ if (hr != DXDIAG_E_INSUFFICIENT_BUFFER)
+ break;
+
+ ok(!memcmp(temp, container, sizeof(WCHAR)*(buffersize - 1)),
+ "Expected truncated container name string, got %s\n", wine_dbgstr_w(container));
+ }
+
+ ok(hr == S_OK,
+ "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, "
+ "got hr = 0x%08x, buffersize = %d\n", hr, buffersize);
+ if (hr == S_OK)
+ trace("pddc[%d] = %s, length = %d\n", index, wine_dbgstr_w(container), buffersize);
+ }
+ else
+ {
+ ok(0, "IDxDiagContainer::EnumChildContainerNames unexpectedly returned 0x%08x\n", hr);
+ break;
+ }
+ }
+
+cleanup:
IDxDiagContainer_Release(pddc);
IDxDiagProvider_Release(pddp);
}
More information about the wine-cvs
mailing list