Commit aa95731d authored by Aric Stewart's avatar Aric Stewart Committed by Alexandre Julliard

Restrict deformating of nested index keys [[1]].

Introduce the beginning of group deformating {}.
parent dd5b70b4
...@@ -50,6 +50,11 @@ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msifo ...@@ -50,6 +50,11 @@ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msifo
WINE_DEFAULT_DEBUG_CHANNEL(msi); WINE_DEFAULT_DEBUG_CHANNEL(msi);
static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr,
WCHAR** data, DWORD len, MSIRECORD* record,
BOOL* in_group);
LPWSTR build_default_format(MSIRECORD* record) LPWSTR build_default_format(MSIRECORD* record)
{ {
int i; int i;
...@@ -239,6 +244,45 @@ static LPWSTR deformat_property(MSIPACKAGE* package, LPCWSTR key, DWORD* chunk) ...@@ -239,6 +244,45 @@ static LPWSTR deformat_property(MSIPACKAGE* package, LPCWSTR key, DWORD* chunk)
return value; return value;
} }
/*
* Groups cannot be nested. They are just treated as from { to next }
*/
static BOOL find_next_group(LPCWSTR source, DWORD len_remaining,
LPWSTR *group, LPCWSTR *mark,
LPCWSTR* mark2)
{
int i;
BOOL found = FALSE;
*mark = scanW(source,'{',len_remaining);
if (!*mark)
return FALSE;
for (i = 1; (*mark - source) + i < len_remaining; i++)
{
if ((*mark)[i] == '}')
{
found = TRUE;
break;
}
}
if (! found)
return FALSE;
*mark2 = &(*mark)[i];
i = *mark2 - *mark;
*group = HeapAlloc(GetProcessHeap(),0,i*sizeof(WCHAR));
i -= 1;
memcpy(*group,&(*mark)[1],i*sizeof(WCHAR));
(*group)[i] = 0;
TRACE("Found group %s\n",debugstr_w(*group));
return TRUE;
}
static BOOL find_next_outermost_key(LPCWSTR source, DWORD len_remaining, static BOOL find_next_outermost_key(LPCWSTR source, DWORD len_remaining,
LPWSTR *key, LPCWSTR *mark, LPCWSTR* mark2, LPWSTR *key, LPCWSTR *mark, LPCWSTR* mark2,
BOOL *nested) BOOL *nested)
...@@ -284,13 +328,71 @@ static BOOL find_next_outermost_key(LPCWSTR source, DWORD len_remaining, ...@@ -284,13 +328,71 @@ static BOOL find_next_outermost_key(LPCWSTR source, DWORD len_remaining,
return TRUE; return TRUE;
} }
LPWSTR deformat_group(MSIPACKAGE* package, LPWSTR group, DWORD len,
MSIRECORD* record, DWORD* size)
{
LPWSTR value;
LPCWSTR mark, mark2;
LPWSTR key;
BOOL nested;
INT failcount;
static const WCHAR fmt[] = {'{','%','s','}',0};
UINT sz;
if (!group || group[0] == 0)
{
*size = 0;
return NULL;
}
/* if no [] then group is returned as is */
if (!find_next_outermost_key(group, len, &key, &mark, &mark2, &nested))
{
*size = (len+2)*sizeof(WCHAR);
value = HeapAlloc(GetProcessHeap(),0,*size);
sprintfW(value,fmt,group);
/* do not return size of the null at the end */
*size = (len+1)*sizeof(WCHAR);
return value;
}
HeapFree(GetProcessHeap(),0,key);
failcount = 0;
sz = deformat_string_internal(package, group, &value, strlenW(group),
record, &failcount);
if (failcount==0)
{
*size = sz * sizeof(WCHAR);
return value;
}
else if (failcount < 0)
{
LPWSTR v2;
v2 = HeapAlloc(GetProcessHeap(),0,(sz+2)*sizeof(WCHAR));
v2[0] = '{';
memcpy(&v2[1],value,sz*sizeof(WCHAR));
v2[sz+1]='}';
HeapFree(GetProcessHeap(),0,value);
*size = (sz+2)*sizeof(WCHAR);
return v2;
}
else
{
*size = 0;
return NULL;
}
}
/* /*
* len is in WCHARs * len is in WCHARs
* return is also in WCHARs * return is also in WCHARs
*/ */
static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr,
WCHAR** data, DWORD len, MSIRECORD* record) WCHAR** data, DWORD len, MSIRECORD* record,
INT* failcount)
{ {
LPCWSTR mark = NULL; LPCWSTR mark = NULL;
LPCWSTR mark2 = NULL; LPCWSTR mark2 = NULL;
...@@ -313,7 +415,8 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, ...@@ -313,7 +415,8 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr,
TRACE("Starting with %s\n",debugstr_w(ptr)); TRACE("Starting with %s\n",debugstr_w(ptr));
/* scan for special characters... fast exit */ /* scan for special characters... fast exit */
if (!scanW(ptr,'[',len) || (scanW(ptr,'[',len) && !scanW(ptr,']',len))) if ((!scanW(ptr,'[',len) || (scanW(ptr,'[',len) && !scanW(ptr,']',len))) &&
(scanW(ptr,'{',len) && !scanW(ptr,'}',len)))
{ {
/* not formatted */ /* not formatted */
*data = HeapAlloc(GetProcessHeap(),0,(len*sizeof(WCHAR))); *data = HeapAlloc(GetProcessHeap(),0,(len*sizeof(WCHAR)));
...@@ -326,9 +429,18 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, ...@@ -326,9 +429,18 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr,
while (progress - ptr < len) while (progress - ptr < len)
{ {
/* seek out first group if existing */
if (find_next_group(progress, len - (progress - ptr), &key,
&mark, &mark2))
{
value = deformat_group(package, key, strlenW(key)+1, record,
&chunk);
key = NULL;
nested = FALSE;
}
/* formatted string located */ /* formatted string located */
if (!find_next_outermost_key(progress, len - (progress - ptr), &key, else if (!find_next_outermost_key(progress, len - (progress - ptr),
&mark, &mark2, &nested)) &key, &mark, &mark2, &nested))
{ {
LPBYTE nd2; LPBYTE nd2;
...@@ -368,7 +480,7 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, ...@@ -368,7 +480,7 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr,
{ {
TRACE("Nested key... %s\n",debugstr_w(key)); TRACE("Nested key... %s\n",debugstr_w(key));
deformat_string_internal(package, key, &value, strlenW(key)+1, deformat_string_internal(package, key, &value, strlenW(key)+1,
record); record, failcount);
HeapFree(GetProcessHeap(),0,key); HeapFree(GetProcessHeap(),0,key);
key = value; key = value;
...@@ -379,22 +491,31 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, ...@@ -379,22 +491,31 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr,
if (!package) if (!package)
{ {
/* only deformat number indexs */ /* only deformat number indexs */
if (is_key_number(key)) if (key && is_key_number(key))
{
value = deformat_index(record,key,&chunk); value = deformat_index(record,key,&chunk);
if (!chunk && failcount && *failcount >= 0)
(*failcount)++;
}
else else
{ {
DWORD keylen = strlenW(key); if (failcount)
chunk = (keylen + 2)*sizeof(WCHAR); *failcount = -1;
value = HeapAlloc(GetProcessHeap(),0,chunk); if(key)
value[0] = '['; {
memcpy(&value[1],key,keylen*sizeof(WCHAR)); DWORD keylen = strlenW(key);
value[1+keylen] = ']'; chunk = (keylen + 2)*sizeof(WCHAR);
value = HeapAlloc(GetProcessHeap(),0,chunk);
value[0] = '[';
memcpy(&value[1],key,keylen*sizeof(WCHAR));
value[1+keylen] = ']';
}
} }
} }
else else
{ {
sz = 0; sz = 0;
switch (key[0]) if (key) switch (key[0])
{ {
case '~': case '~':
value = deformat_NULL(&chunk); value = deformat_NULL(&chunk);
...@@ -415,8 +536,17 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, ...@@ -415,8 +536,17 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr,
value = deformat_environment(package,&key[1],&chunk); value = deformat_environment(package,&key[1],&chunk);
break; break;
default: default:
/* index keys cannot be nested */
if (is_key_number(key)) if (is_key_number(key))
value = deformat_index(record,key,&chunk); if (!nested)
value = deformat_index(record,key,&chunk);
else
{
static const WCHAR fmt[] = {'[','%','s',']',0};
value = HeapAlloc(GetProcessHeap(),0,10);
sprintfW(value,fmt,key);
chunk = strlenW(value)*sizeof(WCHAR);
}
else else
value = deformat_property(package,key,&chunk); value = deformat_property(package,key,&chunk);
break; break;
...@@ -439,6 +569,8 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, ...@@ -439,6 +569,8 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr,
size+=chunk; size+=chunk;
HeapFree(GetProcessHeap(),0,value); HeapFree(GetProcessHeap(),0,value);
} }
else if (failcount && *failcount >=0 )
(*failcount)++;
progress = mark2+1; progress = mark2+1;
} }
...@@ -467,7 +599,7 @@ UINT MSI_FormatRecordW( MSIPACKAGE* package, MSIRECORD* record, LPWSTR buffer, ...@@ -467,7 +599,7 @@ UINT MSI_FormatRecordW( MSIPACKAGE* package, MSIRECORD* record, LPWSTR buffer,
TRACE("(%s)\n",debugstr_w(rec)); TRACE("(%s)\n",debugstr_w(rec));
len = deformat_string_internal(package,rec,&deformated,strlenW(rec), len = deformat_string_internal(package,rec,&deformated,strlenW(rec),
record); record, NULL);
if (buffer) if (buffer)
{ {
...@@ -514,7 +646,7 @@ UINT MSI_FormatRecordA( MSIPACKAGE* package, MSIRECORD* record, LPSTR buffer, ...@@ -514,7 +646,7 @@ UINT MSI_FormatRecordA( MSIPACKAGE* package, MSIRECORD* record, LPSTR buffer,
TRACE("(%s)\n",debugstr_w(rec)); TRACE("(%s)\n",debugstr_w(rec));
len = deformat_string_internal(package,rec,&deformated,strlenW(rec), len = deformat_string_internal(package,rec,&deformated,strlenW(rec),
record); record, NULL);
lenA = WideCharToMultiByte(CP_ACP,0,deformated,len,NULL,0,NULL,NULL); lenA = WideCharToMultiByte(CP_ACP,0,deformated,len,NULL,0,NULL,NULL);
if (buffer) if (buffer)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment