msi: format.c, fix nested [ ]

Aric Stewart aric at codeweavers.com
Mon Jan 31 17:51:26 CST 2005


cleanup processing a bit more.
Allow for nested keys to work properly.

-------------- next part --------------
Index: format.c
===================================================================
RCS file: /cvstrees/crossover/office/wine/dlls/msi/format.c,v
retrieving revision 1.7
diff -u -u -r1.7 format.c
--- format.c	31 Jan 2005 03:00:03 -0000	1.7
+++ format.c	31 Jan 2005 23:42:40 -0000
@@ -79,7 +79,6 @@
     return NULL;
 }
 
-
 /* break out helper functions for deformating */
 static LPWSTR deformat_component(MSIPACKAGE* package, LPCWSTR key, DWORD* sz)
 {
@@ -171,6 +170,9 @@
 static BOOL is_key_number(LPCWSTR key)
 {
     INT index = 0;
+    if (key[0] == 0)
+        return FALSE;
+
     while (isdigitW(key[index])) index++;
     if (key[index] == 0)
         return TRUE;
@@ -212,6 +214,52 @@
     return value;
 }
 
+static BOOL find_next_outermost_key(LPCWSTR source, DWORD len_remaining,
+                                    LPWSTR *key, LPCWSTR *mark, LPCWSTR* mark2, 
+                                    BOOL *nested)
+{
+    INT count = 0;
+    INT total_count = 0;
+    int i;
+
+    *mark = scanW(source,'[',len_remaining);
+    if (!*mark)
+        return FALSE;
+
+    count = 1;
+    total_count = 1;
+    *nested = FALSE;
+    for (i = 1; (*mark - source) + i < len_remaining && count > 0; i++)
+    {
+        if ((*mark)[i] == '[') 
+        {
+            count ++;
+            total_count ++;
+            *nested = TRUE;
+        }
+        else if ((*mark)[i] == ']')
+        {
+            count --;
+        }
+    }
+
+    if (count > 0)
+        return FALSE;
+
+    *mark2 = &(*mark)[i-1]; 
+
+    i = *mark2 - *mark;
+    *key = HeapAlloc(GetProcessHeap(),0,i*sizeof(WCHAR));
+    /* do not have the [] in the key */
+    i -= 1;
+    strncpyW(*key,&(*mark)[1],i);
+    (*key)[i] = 0;
+
+    TRACE("Found Key %s\n",debugstr_w(*key));
+    return TRUE;
+}
+
+
 /*
  * len is in WCHARs
  * return is also in WCHARs
@@ -219,15 +267,16 @@
 static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, 
                                      WCHAR** data, DWORD len, MSIRECORD* record)
 {
-    const WCHAR* mark=NULL;
-    WCHAR* mark2;
+    LPCWSTR mark = NULL;
+    LPCWSTR mark2 = NULL;
     DWORD size=0;
     DWORD chunk=0;
-    WCHAR key[0x100];
+    LPWSTR key;
     LPWSTR value = NULL;
     DWORD sz;
     LPBYTE newdata = NULL;
     const WCHAR* progress = NULL;
+    BOOL nested;
 
     if (ptr==NULL)
     {
@@ -253,18 +302,18 @@
     while (progress - ptr < len)
     { 
         /* formatted string located */ 
-        mark = scanW(progress,'[',len - (progress-ptr));
-        if (!mark)
+        if (!find_next_outermost_key(progress, len - (progress - ptr), &key,
+                                     &mark, &mark2, &nested))
         {
             TRACE("after value %s .. %s\n",debugstr_w((LPWSTR)newdata),
                                        debugstr_w(mark));
             LPBYTE nd2;
             chunk = (len - (progress - ptr)) * sizeof(WCHAR);
-            TRACE("after chunk is %li\n",chunk);
+            TRACE("after chunk is %li + %li\n",size,chunk);
             if (size)
                 nd2 = HeapReAlloc(GetProcessHeap(),0,newdata,(size+chunk));
             else
-                nd2 = HeapAlloc(GetProcessHeap(),0,size);
+                nd2 = HeapAlloc(GetProcessHeap(),0,chunk);
 
             newdata = nd2;
             memcpy(&newdata[size],progress,chunk);
@@ -289,13 +338,16 @@
 
         progress = mark;
 
-        mark++;
-        /* there should be no null characters in a key so strchrW is ok */
-        mark2 = strchrW(mark,']');
-        strncpyW(key,mark,mark2-mark);
-        key[mark2-mark] = 0;
-        mark = strchrW(mark,']');
-        mark++;
+        if (nested)
+        {
+            TRACE("Nested key... %s\n",debugstr_w(key));
+            deformat_string_internal(package, key, &value, strlenW(key)+1,
+                                     record);
+
+            HeapFree(GetProcessHeap(),0,key);
+            key = value;
+        }
+
         TRACE("Current %s .. %s\n",debugstr_w((LPWSTR)newdata),debugstr_w(key));
 
         if (!package)
@@ -307,7 +359,9 @@
             {
                 chunk = (strlenW(key) + 2)*sizeof(WCHAR);
                 value = HeapAlloc(GetProcessHeap(),0,chunk);
-                memcpy(value,progress,chunk);
+                value[0] = '[';
+                memcpy(&value[1],key,strlenW(key)*sizeof(WCHAR));
+                value[strlenW(key)+1] = ']';
             }
         }
         else
@@ -339,6 +393,9 @@
                 break;      
             }
         }
+
+        HeapFree(GetProcessHeap(),0,key);
+
         if (value!=NULL)
         {
             LPBYTE nd2;


More information about the wine-patches mailing list