arbitrary characters allowed in wxFileConfig entry names
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1889 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -67,22 +67,16 @@
|
|||||||
// global functions declarations
|
// global functions declarations
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// is 'c' a valid character in group name?
|
|
||||||
// NB: wxCONFIG_IMMUTABLE_PREFIX and wxCONFIG_PATH_SEPARATOR must be valid chars,
|
|
||||||
// but _not_ ']' (group name delimiter)
|
|
||||||
// NB2: we explicitly allow symbols from the 2nd half of the ASCII table
|
|
||||||
inline bool IsValid(char c)
|
|
||||||
{
|
|
||||||
return isalnum(c) || strchr("@_/-!.*%", c) || ((c & 0x80) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// compare functions for sorting the arrays
|
// compare functions for sorting the arrays
|
||||||
static int CompareEntries(ConfigEntry *p1, ConfigEntry *p2);
|
static int CompareEntries(ConfigEntry *p1, ConfigEntry *p2);
|
||||||
static int CompareGroups(ConfigGroup *p1, ConfigGroup *p2);
|
static int CompareGroups(ConfigGroup *p1, ConfigGroup *p2);
|
||||||
|
|
||||||
// filter strings
|
// filter strings
|
||||||
static wxString FilterIn(const wxString& str);
|
static wxString FilterInValue(const wxString& str);
|
||||||
static wxString FilterOut(const wxString& str);
|
static wxString FilterOutValue(const wxString& str);
|
||||||
|
|
||||||
|
static wxString FilterInEntryName(const wxString& str);
|
||||||
|
static wxString FilterOutEntryName(const wxString& str);
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
@@ -299,7 +293,7 @@ void wxFileConfig::Parse(wxTextFile& file, bool bLocal)
|
|||||||
pEnd = pStart;
|
pEnd = pStart;
|
||||||
|
|
||||||
while ( *++pEnd != ']' ) {
|
while ( *++pEnd != ']' ) {
|
||||||
if ( !IsValid(*pEnd) && *pEnd != ' ' ) // allow spaces in group names
|
if ( *pEnd == '\n' || *pEnd == '\0' )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,7 +306,8 @@ void wxFileConfig::Parse(wxTextFile& file, bool bLocal)
|
|||||||
// group name here is always considered as abs path
|
// group name here is always considered as abs path
|
||||||
wxString strGroup;
|
wxString strGroup;
|
||||||
pStart++;
|
pStart++;
|
||||||
strGroup << wxCONFIG_PATH_SEPARATOR << wxString(pStart, pEnd - pStart);
|
strGroup << wxCONFIG_PATH_SEPARATOR
|
||||||
|
<< FilterInEntryName(wxString(pStart, pEnd - pStart));
|
||||||
|
|
||||||
// will create it if doesn't yet exist
|
// will create it if doesn't yet exist
|
||||||
SetPath(strGroup);
|
SetPath(strGroup);
|
||||||
@@ -344,10 +339,17 @@ void wxFileConfig::Parse(wxTextFile& file, bool bLocal)
|
|||||||
}
|
}
|
||||||
else { // a key
|
else { // a key
|
||||||
const char *pEnd = pStart;
|
const char *pEnd = pStart;
|
||||||
while ( IsValid(*pEnd) )
|
while ( !isspace(*pEnd) ) {
|
||||||
|
if ( *pEnd == '\\' ) {
|
||||||
|
// next character may be space or not - still take it because it's
|
||||||
|
// quoted
|
||||||
pEnd++;
|
pEnd++;
|
||||||
|
}
|
||||||
|
|
||||||
wxString strKey(pStart, pEnd);
|
pEnd++;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString strKey(FilterInEntryName(wxString(pStart, pEnd)));
|
||||||
|
|
||||||
// skip whitespace
|
// skip whitespace
|
||||||
while ( isspace(*pEnd) )
|
while ( isspace(*pEnd) )
|
||||||
@@ -394,7 +396,7 @@ void wxFileConfig::Parse(wxTextFile& file, bool bLocal)
|
|||||||
while ( isspace(*pEnd) )
|
while ( isspace(*pEnd) )
|
||||||
pEnd++;
|
pEnd++;
|
||||||
|
|
||||||
pEntry->SetValue(FilterIn(pEnd), FALSE /* read from file */);
|
pEntry->SetValue(FilterInValue(pEnd), FALSE /* read from file */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -591,7 +593,7 @@ bool wxFileConfig::Write(const wxString& key, const wxString& szValue)
|
|||||||
wxString strName = path.Name();
|
wxString strName = path.Name();
|
||||||
if ( strName.IsEmpty() ) {
|
if ( strName.IsEmpty() ) {
|
||||||
// setting the value of a group is an error
|
// setting the value of a group is an error
|
||||||
wxASSERT_MSG( IsEmpty(szValue), _("can't set value of a group!") );
|
wxASSERT_MSG( IsEmpty(szValue), "can't set value of a group!" );
|
||||||
|
|
||||||
// ... except if it's empty in which case it's a way to force it's creation
|
// ... except if it's empty in which case it's a way to force it's creation
|
||||||
m_pCurrentGroup->SetDirty();
|
m_pCurrentGroup->SetDirty();
|
||||||
@@ -604,18 +606,12 @@ bool wxFileConfig::Write(const wxString& key, const wxString& szValue)
|
|||||||
|
|
||||||
// check that the name is reasonable
|
// check that the name is reasonable
|
||||||
if ( strName[0u] == wxCONFIG_IMMUTABLE_PREFIX ) {
|
if ( strName[0u] == wxCONFIG_IMMUTABLE_PREFIX ) {
|
||||||
wxLogError(_("Entry name can't start with '%c'."),
|
wxLogError(_("Config entry name cannot start with '%c'."),
|
||||||
wxCONFIG_IMMUTABLE_PREFIX);
|
wxCONFIG_IMMUTABLE_PREFIX);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( const char *pc = strName; *pc != '\0'; pc++ ) {
|
strName = FilterOutEntryName(strName);
|
||||||
if ( !IsValid(*pc) ) {
|
|
||||||
wxLogError(_("Character '%c' is invalid in a config entry name."),
|
|
||||||
*pc);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigEntry *pEntry = m_pCurrentGroup->FindEntry(strName);
|
ConfigEntry *pEntry = m_pCurrentGroup->FindEntry(strName);
|
||||||
if ( pEntry == NULL )
|
if ( pEntry == NULL )
|
||||||
@@ -1278,7 +1274,7 @@ void ConfigEntry::SetValue(const wxString& strValue, bool bUser)
|
|||||||
m_strValue = strValue;
|
m_strValue = strValue;
|
||||||
|
|
||||||
if ( bUser ) {
|
if ( bUser ) {
|
||||||
wxString strVal = FilterOut(strValue);
|
wxString strVal = FilterOutValue(strValue);
|
||||||
wxString strLine;
|
wxString strLine;
|
||||||
strLine << m_strName << " = " << strVal;
|
strLine << m_strName << " = " << strVal;
|
||||||
|
|
||||||
@@ -1337,8 +1333,8 @@ int CompareGroups(ConfigGroup *p1,
|
|||||||
// filter functions
|
// filter functions
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// undo FilterOut
|
// undo FilterOutValue
|
||||||
wxString FilterIn(const wxString& str)
|
static wxString FilterInValue(const wxString& str)
|
||||||
{
|
{
|
||||||
wxString strResult;
|
wxString strResult;
|
||||||
strResult.Alloc(str.Len());
|
strResult.Alloc(str.Len());
|
||||||
@@ -1384,9 +1380,9 @@ wxString FilterIn(const wxString& str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// quote the string before writing it to file
|
// quote the string before writing it to file
|
||||||
wxString FilterOut(const wxString& str)
|
static wxString FilterOutValue(const wxString& str)
|
||||||
{
|
{
|
||||||
if(str.IsEmpty())
|
if ( !str )
|
||||||
return str;
|
return str;
|
||||||
|
|
||||||
wxString strResult;
|
wxString strResult;
|
||||||
@@ -1439,9 +1435,41 @@ wxString FilterOut(const wxString& str)
|
|||||||
return strResult;
|
return strResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// undo FilterOutEntryName
|
||||||
|
static wxString FilterInEntryName(const wxString& str)
|
||||||
|
{
|
||||||
|
wxString strResult;
|
||||||
|
strResult.Alloc(str.Len());
|
||||||
|
|
||||||
|
for ( const char *pc = str.c_str(); *pc != '\0'; pc++ ) {
|
||||||
|
if ( *pc == '\\' )
|
||||||
|
pc++;
|
||||||
|
|
||||||
|
strResult += *pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanitize entry or group name: insert '\\' before any special characters
|
||||||
|
static wxString FilterOutEntryName(const wxString& str)
|
||||||
|
{
|
||||||
|
wxString strResult;
|
||||||
|
strResult.Alloc(str.Len());
|
||||||
|
|
||||||
|
for ( const char *pc = str.c_str(); *pc != '\0'; pc++ ) {
|
||||||
|
char c = *pc;
|
||||||
|
|
||||||
|
// we explicitly allow some of "safe" chars and 8bit ASCII characters
|
||||||
|
// which will probably never have special meaning
|
||||||
|
// NB: note that wxCONFIG_IMMUTABLE_PREFIX and wxCONFIG_PATH_SEPARATOR
|
||||||
|
// should *not* be quoted
|
||||||
|
if ( !isalnum(c) && !strchr("@_/-!.*%", c) && ((c & 0x80) == 0) )
|
||||||
|
strResult += '\\';
|
||||||
|
|
||||||
|
strResult += c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user