Commit ee197557 authored by Andy Cedilnik's avatar Andy Cedilnik
Browse files

ENH: Allow blocking of writing into the source tree

parent 10efe3b0
......@@ -204,6 +204,27 @@ bool cmAddCustomCommandCommand::InitialPass(
return false;
}
if ( !this->Makefile->CanIWriteThisFile(output.c_str()) )
{
std::string e = "attempted to have a file: " + output +
" in a source directory as an output of custom command.";
this->SetError(e.c_str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
std::vector<std::string>::iterator oit;
for ( oit = outputs.begin(); oit != outputs.end(); ++ oit )
{
if ( !this->Makefile->CanIWriteThisFile(oit->c_str()) )
{
std::string e = "attempted to have a file: " + *oit +
" in a source directory as an output of custom command.";
this->SetError(e.c_str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
}
std::string::size_type pos = output.find_first_of("#<>");
if(pos != output.npos)
{
......@@ -213,6 +234,7 @@ bool cmAddCustomCommandCommand::InitialPass(
this->SetError(msg.str().c_str());
return false;
}
// Choose which mode of the command to use.
if(source.empty() && output.empty())
{
......
......@@ -28,6 +28,13 @@ bool cmConfigureFileCommand::InitialPass(std::vector<std::string> const& args)
}
this->InputFile = args[0];
this->OuputFile = args[1];
if ( !this->Makefile->CanIWriteThisFile(this->OuputFile.c_str()) )
{
std::string e = "attempted to configure a file: " + this->OuputFile + " into a source directory.";
this->SetError(e.c_str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
this->CopyOnly = false;
this->EscapeQuotes = false;
......
......@@ -171,6 +171,15 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args)
}
}
if ( !this->Makefile->CanIWriteThisFile(output_file.c_str()) )
{
std::string e = "attempted to output into a file: " + output_file
+ " into a source directory.";
this->SetError(e.c_str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
// Check for commands given.
if(cmds.empty())
{
......
......@@ -102,6 +102,13 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
{
message += *i;
}
if ( !this->Makefile->CanIWriteThisFile(fileName.c_str()) )
{
std::string e = "attempted to write a file: " + fileName + " into a source directory.";
this->SetError(e.c_str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
std::string dir = cmSystemTools::GetFilenamePath(fileName);
cmSystemTools::MakeDirectory(dir.c_str());
......@@ -279,6 +286,14 @@ bool cmFileCommand::HandleMakeDirectoryCommand(
expr += "/" + *i;
cdir = &expr;
}
if ( !this->Makefile->CanIWriteThisFile(cdir->c_str()) )
{
std::string e = "attempted to create a directory: " + *cdir
+ " into a source directory.";
this->SetError(e.c_str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
if ( !cmSystemTools::MakeDirectory(cdir->c_str()) )
{
std::string error = "problem creating directory: " + *cdir;
......
......@@ -24,6 +24,14 @@ bool cmMakeDirectoryCommand::InitialPass(std::vector<std::string> const& args)
this->SetError("called with incorrect number of arguments");
return false;
}
if ( !this->Makefile->CanIWriteThisFile(args[0].c_str()) )
{
std::string e = "attempted to create a directory: " + args[0]
+ " into a source directory.";
this->SetError(e.c_str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
cmSystemTools::MakeDirectory(args[0].c_str());
return true;
}
......
......@@ -1320,6 +1320,33 @@ bool cmMakefile::IsSet(const char* name) const
return true;
}
bool cmMakefile::CanIWriteThisFile(const char* fileName)
{
if ( !this->IsOn("CMAKE_DISABLE_SOURCE_CHANGES") )
{
return 0;
}
// If we are doing an in-source build, than the test will always fail
if ( cmSystemTools::SameFile(this->GetHomeDirectory(), this->GetHomeOutputDirectory()) )
{
if ( this->IsOn("CMAKE_DISABLE_IN_SOURCE_BUILD") )
{
return false;
}
return true;
}
// Check if this is subdirectory of the source tree but not a subdirectory of a build tree
if ( cmSystemTools::IsSubDirectory(fileName,
this->GetHomeDirectory()) &&
!cmSystemTools::IsSubDirectory(fileName,
this->GetHomeOutputDirectory()) )
{
return false;
}
return true;
}
const char* cmMakefile::GetRequiredDefinition(const char* name) const
{
const char* ret = this->GetDefinition(name);
......@@ -2328,6 +2355,11 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
bool copyonly, bool atOnly, bool escapeQuotes)
{
int res = 1;
if ( !this->CanIWriteThisFile(outfile) )
{
cmSystemTools::Error("Attempt to write file: ", outfile, " into a source directory.");
return 0;
}
if ( !cmSystemTools::FileExists(infile) )
{
cmSystemTools::Error("File ", infile, " does not exist.");
......
......@@ -494,6 +494,11 @@ public:
*/
const char* GetDefineFlags()
{return this->DefineFlags.c_str();}
/**
* Make sure CMake can write this file
*/
bool CanIWriteThisFile(const char* fileName);
/**
* Get the vector of used command instances.
......
......@@ -45,6 +45,16 @@ bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args)
message += *i;
}
}
if ( !this->Makefile->CanIWriteThisFile(fileName.c_str()) )
{
std::string e = "attempted to write a file: " + fileName
+ " into a source directory.";
this->SetError(e.c_str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
std::string dir = cmSystemTools::GetFilenamePath(fileName);
cmSystemTools::MakeDirectory(dir.c_str());
......
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