Rob Shearman : rpcrt4: Don't crash in RpcStringBindingParseA/ W if Endpoint or Options is NULL.

Alexandre Julliard julliard at winehq.org
Thu Feb 28 06:21:43 CST 2008


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

Author: Rob Shearman <rob at codeweavers.com>
Date:   Wed Feb 27 19:02:54 2008 +0000

rpcrt4: Don't crash in RpcStringBindingParseA/W if Endpoint or Options is NULL.

---

 dlls/rpcrt4/rpc_binding.c |   50 ++++++++++++++++++++++++++++----------------
 1 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/dlls/rpcrt4/rpc_binding.c b/dlls/rpcrt4/rpc_binding.c
index 3a8afde..19272af 100644
--- a/dlls/rpcrt4/rpc_binding.c
+++ b/dlls/rpcrt4/rpc_binding.c
@@ -468,6 +468,7 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU
 {
   CHAR *data, *next;
   static const char ep_opt[] = "endpoint=";
+  BOOL endpoint_already_found = FALSE;
 
   TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_a((char*)StringBinding),
        ObjUuid, Protseq, NetworkAddr, Endpoint, Options);
@@ -513,22 +514,28 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU
       next = strchr(opt, '=');
       if (!next) {
         /* not an option, must be an endpoint */
-        if (*Endpoint) goto fail;
-        *Endpoint = (unsigned char*) opt;
+        if (endpoint_already_found) goto fail;
+        if (Endpoint) *Endpoint = (unsigned char*) opt;
+        else HeapFree(GetProcessHeap(), 0, opt);
+        endpoint_already_found = TRUE;
       } else {
         if (strncmp(opt, ep_opt, strlen(ep_opt)) == 0) {
           /* endpoint option */
-          if (*Endpoint) goto fail;
-          *Endpoint = (unsigned char*) RPCRT4_strdupA(next+1);
+          if (endpoint_already_found) goto fail;
+          if (Endpoint) *Endpoint = (unsigned char*) RPCRT4_strdupA(next+1);
           HeapFree(GetProcessHeap(), 0, opt);
+          endpoint_already_found = TRUE;
         } else {
           /* network option */
-          if (*Options) {
-            /* FIXME: this is kind of inefficient */
-            *Options = (unsigned char*) RPCRT4_strconcatA( (char*)*Options, opt);
+          if (Options) {
+            if (*Options) {
+              /* FIXME: this is kind of inefficient */
+              *Options = (unsigned char*) RPCRT4_strconcatA( (char*)*Options, opt);
+              HeapFree(GetProcessHeap(), 0, opt);
+            } else
+              *Options = (unsigned char*) opt;
+          } else
             HeapFree(GetProcessHeap(), 0, opt);
-          } else 
-	    *Options = (unsigned char*) opt;
         }
       }
     }
@@ -559,6 +566,7 @@ RPC_STATUS WINAPI RpcStringBindingParseW( RPC_WSTR StringBinding, RPC_WSTR *ObjU
 {
   WCHAR *data, *next;
   static const WCHAR ep_opt[] = {'e','n','d','p','o','i','n','t','=',0};
+  BOOL endpoint_already_found = FALSE;
 
   TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_w(StringBinding),
        ObjUuid, Protseq, NetworkAddr, Endpoint, Options);
@@ -604,22 +612,28 @@ RPC_STATUS WINAPI RpcStringBindingParseW( RPC_WSTR StringBinding, RPC_WSTR *ObjU
       next = strchrW(opt, '=');
       if (!next) {
         /* not an option, must be an endpoint */
-        if (*Endpoint) goto fail;
-        *Endpoint = opt;
+        if (endpoint_already_found) goto fail;
+        if (Endpoint) *Endpoint = opt;
+        else HeapFree(GetProcessHeap(), 0, opt);
+        endpoint_already_found = TRUE;
       } else {
         if (strncmpW(opt, ep_opt, strlenW(ep_opt)) == 0) {
           /* endpoint option */
-          if (*Endpoint) goto fail;
-          *Endpoint = RPCRT4_strdupW(next+1);
+          if (endpoint_already_found) goto fail;
+          if (Endpoint) *Endpoint = RPCRT4_strdupW(next+1);
           HeapFree(GetProcessHeap(), 0, opt);
+          endpoint_already_found = TRUE;
         } else {
           /* network option */
-          if (*Options) {
-            /* FIXME: this is kind of inefficient */
-            *Options = RPCRT4_strconcatW(*Options, opt);
+          if (Options) {
+            if (*Options) {
+              /* FIXME: this is kind of inefficient */
+              *Options = RPCRT4_strconcatW(*Options, opt);
+              HeapFree(GetProcessHeap(), 0, opt);
+            } else
+              *Options = opt;
+          } else
             HeapFree(GetProcessHeap(), 0, opt);
-          } else 
-	    *Options = opt;
         }
       }
     }




More information about the wine-cvs mailing list