Xcode: Escape all backslashes in strings (#15328)

Before this change backslashes in strings were escaped during compile
flags adds via AppendFlag(). But global flags like OTHER_CPLUSPLUSFLAGS
are not added as flags but as plain strings so they were not escaped
properly.

Now the escaping is performed within cmXCodeObject::PrintString() which
ensures that strings are always encoded.
This commit is contained in:
Gregor Jasny 2015-12-27 16:33:46 +01:00 committed by Brad King
parent 90b50b2e28
commit ba39d7e9d0
6 changed files with 22 additions and 25 deletions

View File

@ -1686,14 +1686,13 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
}
std::string cdir = this->CurrentLocalGenerator->GetCurrentBinaryDirectory();
cdir = this->ConvertToRelativeForXCode(cdir.c_str());
cdir = this->ConvertToRelativeForMake(cdir.c_str());
std::string makecmd = "make -C ";
makecmd += cdir;
makecmd += " -f ";
makecmd += this->ConvertToRelativeForMake(
(makefile+"$CONFIGURATION").c_str());
makecmd += " all";
cmSystemTools::ReplaceString(makecmd, "\\ ", "\\\\ ");
buildphase->AddAttribute("shellScript",
this->CreateString(makecmd.c_str()));
buildphase->AddAttribute("showEnvVarsInLog",
@ -2108,10 +2107,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
this->CurrentLocalGenerator
->GenerateAppleInfoPList(gtgt, "$(EXECUTABLE_NAME)",
plist.c_str());
std::string path =
this->ConvertToRelativeForXCode(plist.c_str());
buildSettings->AddAttribute("INFOPLIST_FILE",
this->CreateString(path.c_str()));
this->CreateString(plist));
}
else if(this->XcodeVersion >= 22)
{
@ -2157,10 +2154,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
this->CurrentLocalGenerator
->GenerateFrameworkInfoPList(gtgt, "$(EXECUTABLE_NAME)",
plist.c_str());
std::string path =
this->ConvertToRelativeForXCode(plist.c_str());
buildSettings->AddAttribute("INFOPLIST_FILE",
this->CreateString(path.c_str()));
this->CreateString(plist));
}
else
{
@ -2200,10 +2195,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
this->CurrentLocalGenerator
->GenerateAppleInfoPList(gtgt, "$(EXECUTABLE_NAME)",
plist.c_str());
std::string path =
this->ConvertToRelativeForXCode(plist.c_str());
buildSettings->AddAttribute("INFOPLIST_FILE",
this->CreateString(path.c_str()));
this->CreateString(plist));
}
}
@ -3880,12 +3873,6 @@ std::string cmGlobalXCodeGenerator::ConvertToRelativeForMake(const char* p)
return cmSystemTools::ConvertToOutputPath(p);
}
//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::ConvertToRelativeForXCode(const char* p)
{
return cmSystemTools::ConvertToOutputPath(p);
}
//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::RelativeToSource(const char* p)
{
@ -4022,8 +4009,8 @@ void cmGlobalXCodeGenerator::AppendFlag(std::string& flags,
// We escape a flag as follows:
// - Place each flag in single quotes ''
// - Escape a single quote as \\'
// - Escape a backslash as \\\\ since it itself is an escape
// - Escape a single quote as \'
// - Escape a backslash as \\ since it itself is an escape
// Note that in the code below we need one more level of escapes for
// C string syntax in this source file.
//
@ -4043,16 +4030,16 @@ void cmGlobalXCodeGenerator::AppendFlag(std::string& flags,
{
if (this->XcodeVersion >= 40)
{
flags += "'\\\\''";
flags += "'\\''";
}
else
{
flags += "\\\\'";
flags += "\\'";
}
}
else if(*c == '\\')
{
flags += "\\\\\\\\";
flags += "\\\\";
}
else
{

View File

@ -99,7 +99,6 @@ private:
std::string XCodeEscapePath(const char* p);
std::string RelativeToSource(const char* p);
std::string RelativeToBinary(const char* p);
std::string ConvertToRelativeForXCode(const char* p);
std::string ConvertToRelativeForMake(const char* p);
void CreateCustomCommands(cmXCodeObject* buildPhases,
cmXCodeObject* sourceBuildPhase,

View File

@ -255,9 +255,9 @@ void cmXCodeObject::PrintString(std::ostream& os,std::string String)
for(std::string::const_iterator i = String.begin();
i != String.end(); ++i)
{
if(*i == '"')
if(*i == '"' || *i == '\\')
{
// Escape double-quotes.
// Escape double-quotes and backslashes.
os << '\\';
}
os << *i;

View File

@ -3,6 +3,7 @@ include(RunCMake)
run_cmake(XcodeFileType)
run_cmake(XcodeAttributeGenex)
run_cmake(XcodeAttributeGenexError)
run_cmake(XcodeObjectNeedsEscape)
run_cmake(XcodeObjectNeedsQuote)
run_cmake(XcodeOptimizationFlags)
run_cmake(XcodePreserveNonOptimizationFlags)

View File

@ -0,0 +1,7 @@
set(expect "-DKDESRCDIR=\\\\\\\\\\\\\"foo\\\\\\\\\\\\\"")
file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodeObjectNeedsEscape.xcodeproj/project.pbxproj actual
REGEX "OTHER_CPLUSPLUSFLAGS = [^;]*;" LIMIT_COUNT 1)
if(NOT "${actual}" MATCHES "${expect}")
message(SEND_ERROR "The actual project contains the line:\n ${actual}\n"
"which does not match expected regex:\n ${expect}\n")
endif()

View File

@ -0,0 +1,3 @@
enable_language(CXX)
string(APPEND CMAKE_CXX_FLAGS " -DKDESRCDIR=\\\"foo\\\"")
add_library(foo STATIC foo.cpp)