Rob Shearman : rpcrt4: Implement NdrConformantStringMemorySize.

Alexandre Julliard julliard at winehq.org
Mon Dec 31 12:32:20 CST 2007


Module: wine
Branch: master
Commit: 86a0b1d24e6f83f6f399850301ca75283b6c0d2b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=86a0b1d24e6f83f6f399850301ca75283b6c0d2b

Author: Rob Shearman <rob at codeweavers.com>
Date:   Sat Dec 29 12:14:30 2007 +0000

rpcrt4: Implement NdrConformantStringMemorySize.

---

 dlls/rpcrt4/ndr_marshall.c |   57 +++++++++++++++++++++++++++++++++++--------
 1 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/dlls/rpcrt4/ndr_marshall.c b/dlls/rpcrt4/ndr_marshall.c
index c517ff1..3b6106f 100644
--- a/dlls/rpcrt4/ndr_marshall.c
+++ b/dlls/rpcrt4/ndr_marshall.c
@@ -790,29 +790,64 @@ void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
   PFORMAT_STRING pFormat )
 {
-  ULONG rslt = 0;
+  ULONG bufsize, memsize, esize, i;
 
-  FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
+  TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
 
-  assert(pStubMsg && pFormat);
+  ReadConformance(pStubMsg, NULL);
+  ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
 
-  if (*pFormat == RPC_FC_C_CSTRING) {
-    rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
+  if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
+  {
+    ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
+        pStubMsg->ActualCount, pStubMsg->MaxCount);
+    RpcRaiseException(RPC_S_INVALID_BOUND);
   }
-  else if (*pFormat == RPC_FC_C_WSTRING) {
-    rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
+  if (pStubMsg->Offset)
+  {
+    ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
+    RpcRaiseException(RPC_S_INVALID_BOUND);
   }
+
+  if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
+  else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
   else {
     ERR("Unhandled string type: %#x\n", *pFormat);
     /* FIXME: raise an exception */
+    esize = 0;
+  }
+
+  memsize = safe_multiply(esize, pStubMsg->MaxCount);
+  bufsize = safe_multiply(esize, pStubMsg->ActualCount);
+
+  /* strings must always have null terminating bytes */
+  if (bufsize < esize)
+  {
+    ERR("invalid string length of %d\n", pStubMsg->ActualCount);
+    RpcRaiseException(RPC_S_INVALID_BOUND);
   }
 
-  if (pFormat[1] != RPC_FC_PAD) {
-    FIXME("sized string format=%d\n", pFormat[1]);
+  /* verify the buffer is safe to access */
+  if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
+      (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
+  {
+    ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
+        pStubMsg->BufferEnd, pStubMsg->Buffer);
+    RpcRaiseException(RPC_X_BAD_STUB_DATA);
   }
 
-  TRACE("  --> %u\n", rslt);
-  return rslt;
+  for (i = bufsize - esize; i < bufsize; i++)
+    if (pStubMsg->Buffer[i] != 0)
+    {
+      ERR("string not null-terminated at byte position %d, data is 0x%x\n",
+        i, pStubMsg->Buffer[i]);
+      RpcRaiseException(RPC_S_INVALID_BOUND);
+    }
+
+  safe_buffer_increment(pStubMsg, bufsize);
+  pStubMsg->MemorySize += memsize;
+
+  return pStubMsg->MemorySize;
 }
 
 /************************************************************************




More information about the wine-cvs mailing list