Restrict deformating of nested index keys [[1]].
Introduce the beginning of group deformating {}.
This commit is contained in:
parent
dd5b70b4bd
commit
aa95731d6f
@ -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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user