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