From 8b23d3b067e126c3d595316bbe6cd113857303bf Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 11 Jul 2012 11:42:43 +0000 Subject: [PATCH] Ensure that names of saved XPMs are valid C identifiers. The name of the XPM should be based on the file name but can't always be exactly equal to it as it's possible (and relatively common, e.g. "foo-24.xpm") to have characters forbidden in identifiers to appear in the file names. Ensure that we use a valid C identifier here. Closes #13905. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72029 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/imagxpm.cpp | 43 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/common/imagxpm.cpp b/src/common/imagxpm.cpp index de2530e84c..17ec2b9143 100644 --- a/src/common/imagxpm.cpp +++ b/src/common/imagxpm.cpp @@ -103,6 +103,45 @@ bool wxXPMHandler::LoadFile(wxImage *image, return true; } +namespace +{ + +// Make the given string a valid C identifier. +// +// All invalid characters are simply replaced by underscores and underscore is +// also prepended in the beginning if the initial character is not alphabetic. +void +MakeValidCIdent(wxString* str) +{ + const wxChar chUnderscore = wxT('_'); + + for ( wxString::iterator it = str->begin(); it != str->end(); ++it ) + { + const wxChar ch = *it; + if ( wxIsdigit(ch) ) + { + if ( it == str->begin() ) + { + // Identifiers can't start with a digit. + str->insert(0, chUnderscore); // prepend underscore + it = str->begin(); // restart as string changed + continue; + } + } + else if ( !wxIsalpha(ch) && ch != chUnderscore ) + { + // Not a valid character in C identifiers. + *it = chUnderscore; + } + } + + // Double underscores are not allowed in normal C identifiers and are + // useless anyhow. + str->Replace(wxT("__"), wxT("_")); +} + +} // anonymous namespace + bool wxXPMHandler::SaveFile(wxImage * image, wxOutputStream& stream, bool WXUNUSED(verbose)) { @@ -124,8 +163,8 @@ bool wxXPMHandler::SaveFile(wxImage * image, wxString sName; if ( image->HasOption(wxIMAGE_OPTION_FILENAME) ) { - wxFileName::SplitPath(image->GetOption(wxIMAGE_OPTION_FILENAME), - NULL, &sName, NULL); + sName = wxFileName(image->GetOption(wxIMAGE_OPTION_FILENAME)).GetName(); + MakeValidCIdent(&sName); sName << wxT("_xpm"); } -- 2.45.2