cmDependsJavaParserHelper: fix dangling pointer

The cmDependsJavaParserHelper tries to implement a "deep copy" in the
assignment operator of the internal class CurrentClass.  To do that, it
uses std::copy and std::back_inserter.  The copy constructor is
implemented in terms of the assignment operator but it does not
initialize the member NestedClasses, a pointer to vector.  This pointer
is dereferenced in the assignment operator.  Change the pointer to a
value and rely on the compiler generated special functions.
This commit is contained in:
Daniel Pfeifer 2016-06-16 23:51:36 +02:00 committed by Brad King
parent f3d76a88b7
commit fe27879c6b
2 changed files with 19 additions and 37 deletions

View File

@ -35,7 +35,7 @@ cmDependsJavaParserHelper::~cmDependsJavaParserHelper()
} }
void cmDependsJavaParserHelper::CurrentClass::AddFileNamesForPrinting( void cmDependsJavaParserHelper::CurrentClass::AddFileNamesForPrinting(
std::vector<std::string>* files, const char* prefix, const char* sep) std::vector<std::string>* files, const char* prefix, const char* sep) const
{ {
std::string rname = ""; std::string rname = "";
if (prefix) { if (prefix) {
@ -44,8 +44,8 @@ void cmDependsJavaParserHelper::CurrentClass::AddFileNamesForPrinting(
} }
rname += this->Name; rname += this->Name;
files->push_back(rname); files->push_back(rname);
std::vector<CurrentClass>::iterator it; std::vector<CurrentClass>::const_iterator it;
for (it = this->NestedClasses->begin(); it != this->NestedClasses->end(); for (it = this->NestedClasses.begin(); it != this->NestedClasses.end();
++it) { ++it) {
it->AddFileNamesForPrinting(files, rname.c_str(), sep); it->AddFileNamesForPrinting(files, rname.c_str(), sep);
} }
@ -191,25 +191,19 @@ void cmDependsJavaParserHelper::StartClass(const char* cls)
void cmDependsJavaParserHelper::EndClass() void cmDependsJavaParserHelper::EndClass()
{ {
CurrentClass* parent = 0; if (this->ClassStack.empty()) {
CurrentClass* current = 0;
if (!this->ClassStack.empty()) {
current = &(*(this->ClassStack.end() - 1));
if (this->ClassStack.size() > 1) {
parent = &(*(this->ClassStack.end() - 2));
}
}
if (current == 0) {
std::cerr << "Error when parsing. Current class is null" << std::endl; std::cerr << "Error when parsing. Current class is null" << std::endl;
abort(); abort();
} }
if (parent == 0) { if (this->ClassStack.size() <= 1) {
std::cerr << "Error when parsing. Parent class is null" << std::endl; std::cerr << "Error when parsing. Parent class is null" << std::endl;
abort(); abort();
} }
CurrentClass& current = this->ClassStack.back();
CurrentClass& parent = this->ClassStack[this->ClassStack.size() - 2];
this->CurrentDepth--; this->CurrentDepth--;
parent->NestedClasses->push_back(*current); parent.NestedClasses.push_back(current);
this->ClassStack.erase(this->ClassStack.end() - 1, this->ClassStack.end()); this->ClassStack.pop_back();
} }
void cmDependsJavaParserHelper::PrintClasses() void cmDependsJavaParserHelper::PrintClasses()
@ -228,10 +222,10 @@ void cmDependsJavaParserHelper::PrintClasses()
std::vector<std::string> cmDependsJavaParserHelper::GetFilesProduced() std::vector<std::string> cmDependsJavaParserHelper::GetFilesProduced()
{ {
std::vector<std::string> files; std::vector<std::string> files;
CurrentClass* toplevel = &(*(this->ClassStack.begin())); CurrentClass const& toplevel = this->ClassStack.front();
std::vector<CurrentClass>::iterator it; std::vector<CurrentClass>::const_iterator it;
for (it = toplevel->NestedClasses->begin(); for (it = toplevel.NestedClasses.begin(); it != toplevel.NestedClasses.end();
it != toplevel->NestedClasses->end(); ++it) { ++it) {
it->AddFileNamesForPrinting(&files, 0, "$"); it->AddFileNamesForPrinting(&files, 0, "$");
} }
return files; return files;
@ -309,11 +303,10 @@ int cmDependsJavaParserHelper::LexInput(char* buf, int maxlen)
if (buf[0] == '\n') { if (buf[0] == '\n') {
this->CurrentLine++; this->CurrentLine++;
} }
return (1); return 1;
} else {
buf[0] = '\n';
return (0);
} }
buf[0] = '\n';
return 0;
} }
void cmDependsJavaParserHelper::Error(const char* str) void cmDependsJavaParserHelper::Error(const char* str)
{ {

View File

@ -48,7 +48,7 @@ public:
// For yacc // For yacc
void AddClassFound(const char* sclass); void AddClassFound(const char* sclass);
void PrepareElement(ParserType* opt); void PrepareElement(ParserType* me);
void DeallocateParserType(char** pt); void DeallocateParserType(char** pt);
void CheckEmpty(int line, int cnt, ParserType* pt); void CheckEmpty(int line, int cnt, ParserType* pt);
void StartClass(const char* cls); void StartClass(const char* cls);
@ -69,20 +69,9 @@ private:
{ {
public: public:
std::string Name; std::string Name;
std::vector<CurrentClass>* NestedClasses; std::vector<CurrentClass> NestedClasses;
CurrentClass() { this->NestedClasses = new std::vector<CurrentClass>; }
~CurrentClass() { delete this->NestedClasses; }
CurrentClass& operator=(CurrentClass const& c)
{
this->NestedClasses->clear();
this->Name = c.Name;
std::copy(c.NestedClasses->begin(), c.NestedClasses->end(),
std::back_inserter(*this->NestedClasses));
return *this;
}
CurrentClass(CurrentClass const& c) { (*this) = c; }
void AddFileNamesForPrinting(std::vector<std::string>* files, void AddFileNamesForPrinting(std::vector<std::string>* files,
const char* prefix, const char* sep); const char* prefix, const char* sep) const;
}; };
std::string CurrentPackage; std::string CurrentPackage;
std::string::size_type InputBufferPos; std::string::size_type InputBufferPos;