Rob Shearman : widl: Fix a memory leak in the server/ stub code when unmarshalling pointers to strings at the top level.

Alexandre Julliard julliard at winehq.org
Mon Mar 9 09:40:36 CDT 2009


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

Author: Rob Shearman <robertshearman at gmail.com>
Date:   Sat Mar  7 23:23:54 2009 +0000

widl: Fix a memory leak in the server/stub code when unmarshalling pointers to strings at the top level.

It is necessary for the first pointer to have an offset to a second
pointer instead of directly to the string type, since the second
pointer frees the memory for the string.

---

 tools/widl/typegen.c |   53 ++++++++++++++++++++++++++++++-------------------
 1 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index ca22825..4c5a96f 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -1546,7 +1546,12 @@ static int write_no_repeat_pointer_descriptions(
         }
         else
         {
-            write_nonsimple_pointer(file, attrs, type, FALSE, type->typestring_offset, typestring_offset);
+            unsigned int offset = type->typestring_offset;
+            /* skip over the pointer that is written for strings, since a
+             * pointer has to be written in-place here */
+            if (is_string_type(attrs, type))
+                offset += 4;
+            write_nonsimple_pointer(file, attrs, type, FALSE, offset, typestring_offset);
         }
 
         align = 0;
@@ -1941,6 +1946,9 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
     unsigned char rtype;
     type_t *elem_type;
 
+    start_offset = *typestring_offset;
+    update_tfsoff(type, start_offset, file);
+
     if (is_declptr(type))
     {
         unsigned char flag = is_conformant_array(type) ? 0 : RPC_FC_P_SIMPLEPOINTER;
@@ -1959,9 +1967,6 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
         }
     }
 
-    start_offset = *typestring_offset;
-    update_tfsoff(type, start_offset, file);
-
     if (is_array(type))
         elem_type = type_array_get_element(type);
     else
@@ -2326,8 +2331,16 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
             }
             else if (type_get_type(ft) == TYPE_ARRAY && type_array_is_decl_as_ptr(ft))
             {
+                unsigned int offset;
+
                 print_file(file, 0, "/* %d */\n", *tfsoff);
-                write_nonsimple_pointer(file, f->attrs, ft, FALSE, ft->typestring_offset, tfsoff);
+
+                offset = ft->typestring_offset;
+                /* skip over the pointer that is written for strings, since a
+                 * pointer has to be written in-place here */
+                if (is_string_type(f->attrs, ft))
+                    offset += 4;
+                write_nonsimple_pointer(file, f->attrs, ft, FALSE, offset, tfsoff);
             }
         }
         if (type_get_real_type(type)->ptrdesc == *tfsoff)
@@ -2633,16 +2646,8 @@ static unsigned int write_typeformatstring_var(FILE *file, int indent, const var
         int ptr_type;
         unsigned int off;
         off = write_array_tfs(file, var->attrs, type, var->name, typeformat_offset);
-        ptr_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
-        /* Top level pointers to conformant arrays may be handled specially
-           since we can bypass the pointer, but if the array is buried
-           beneath another pointer (e.g., "[size_is(,n)] int **p" then we
-           always need to write the pointer.  */
-        if (!ptr_type && var->type != type)
-          /* FIXME:  This should use pointer_default, but the information
-             isn't kept around for arrays.  */
-          ptr_type = RPC_FC_UP;
-        if (ptr_type && ptr_type != RPC_FC_RP)
+        ptr_type = get_pointer_fc(type, var->attrs, toplevel_param);
+        if (ptr_type != RPC_FC_RP)
         {
             unsigned int absoff = type->typestring_offset;
             short reloff = absoff - (*typeformat_offset + 2);
@@ -3352,21 +3357,27 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
             /* strings returned are assumed to be global and hence don't
              * need freeing */
             if (phase != PHASE_FREE || pass != PASS_RETURN)
-            {
-                unsigned int ptr_start_offset = (start_offset - (is_conformant_array(type) ? 4 : 2));
                 print_phase_function(file, indent, "Pointer", local_var_prefix,
-                                     phase, var, ptr_start_offset);
-            }
+                                     phase, var, start_offset);
         }
         else
         {
+            unsigned int real_start_offset = start_offset;
+            /* skip over pointer description straight to string description */
+            if (is_declptr(type))
+            {
+                if (is_conformant_array(type))
+                    real_start_offset += 4;
+                else
+                    real_start_offset += 2;
+            }
             if (is_array(type) && !is_conformant_array(type))
                 print_phase_function(file, indent, "NonConformantString",
                                      local_var_prefix, phase, var,
-                                     start_offset);
+                                     real_start_offset);
             else
                 print_phase_function(file, indent, "ConformantString", local_var_prefix,
-                                     phase, var, start_offset);
+                                     phase, var, real_start_offset);
         }
         break;
     case TGT_ARRAY:




More information about the wine-cvs mailing list