From 2b9b2dd865a42b7d4e4f9b1fd00a28b43561f4be Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Thu, 26 Jan 2017 18:00:33 +0100 Subject: [PATCH] BUG: HashPtrTable has problems with null pointers (issue #395) - print and copy operations should not be allowed to dereference a nullptr. --- .../test/HashPtrTable/Test-hashPtrTable.C | 46 +++++++++++++++++-- .../HashTables/HashPtrTable/HashPtrTable.C | 40 +++++++++++----- .../HashTables/HashPtrTable/HashPtrTable.H | 19 ++++---- .../HashTables/HashPtrTable/HashPtrTableIO.C | 20 ++++++-- 4 files changed, 95 insertions(+), 30 deletions(-) diff --git a/applications/test/HashPtrTable/Test-hashPtrTable.C b/applications/test/HashPtrTable/Test-hashPtrTable.C index 4b792bbae4..5133d784b1 100644 --- a/applications/test/HashPtrTable/Test-hashPtrTable.C +++ b/applications/test/HashPtrTable/Test-hashPtrTable.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -31,15 +31,53 @@ Description using namespace Foam; +template +void printTable(const HashPtrTable& table) +{ + Info<< table.size() << nl << "(" << nl; + + for + ( + typename HashPtrTable::const_iterator iter = table.cbegin(); + iter != table.cend(); + ++iter + ) + { + const T* ptr = *iter; + Info<< iter.key() << " = "; + if (ptr) + { + Info<< *ptr; + } + else + { + Info<< "nullptr"; + } + Info<< nl; + } + + Info<< ")" << endl; +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Main program: int main() { - Foam::HashPtrTable myTable; - myTable.insert("hello", new double(42.1)); + HashPtrTable myTable; + myTable.insert("abc", new double(42.1)); + myTable.insert("def", nullptr); + myTable.insert("ghi", new double(3.14159)); - Info<< myTable << endl; + // Info<< myTable << endl; + printTable(myTable); + + HashPtrTable copy(myTable); + + // Info<< copy << endl; + printTable(copy); + Info<< copy << endl; return 0; } diff --git a/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.C b/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.C index df115134ef..288d16dbc6 100644 --- a/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.C +++ b/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -45,7 +45,15 @@ Foam::HashPtrTable::HashPtrTable { for (const_iterator iter = ht.begin(); iter != ht.end(); ++iter) { - this->insert(iter.key(), new T(**iter)); + const T* ptr = *iter; + if (ptr) + { + this->insert(iter.key(), new T(*ptr)); + } + else + { + this->insert(iter.key(), nullptr); + } } } @@ -62,24 +70,24 @@ Foam::HashPtrTable::~HashPtrTable() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template -T* Foam::HashPtrTable::remove(iterator& it) +T* Foam::HashPtrTable::remove(iterator& iter) { - T* elemPtr = *it; - HashTable::erase(it); - return elemPtr; + T* ptr = *iter; + HashTable::erase(iter); + return ptr; } template -bool Foam::HashPtrTable::erase(iterator& it) +bool Foam::HashPtrTable::erase(iterator& iter) { - T* elemPtr = *it; + T* ptr = *iter; - if (HashTable::erase(it)) + if (HashTable::erase(iter)) { - if (elemPtr) + if (ptr) { - delete elemPtr; + delete ptr; } return true; @@ -128,7 +136,15 @@ void Foam::HashPtrTable::operator= for (const_iterator iter = rhs.begin(); iter != rhs.end(); ++iter) { - this->insert(iter.key(), new T(**iter)); + const T* ptr = *iter; + if (ptr) + { + this->insert(iter.key(), new T(*ptr)); + } + else + { + this->insert(iter.key(), nullptr); + } } } diff --git a/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.H b/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.H index 796076fe22..de85df3bd6 100644 --- a/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.H +++ b/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -70,7 +70,7 @@ class HashPtrTable //- Read from Istream using given Istream constructor class template - void read(Istream&, const INew& inewt); + void read(Istream& is, const INew& inewt); //- Read from dictionary using given dictionary constructor class template @@ -91,17 +91,17 @@ public: //- Construct from Istream using given Istream constructor class template - HashPtrTable(Istream&, const INew&); + HashPtrTable(Istream& is, const INew& inewt); //- Construct from Istream using default Istream constructor class - HashPtrTable(Istream&); + HashPtrTable(Istream& is); //- Construct from dictionary using default dictionary constructor // class - HashPtrTable(const dictionary&); + HashPtrTable(const dictionary& dict); //- Construct as copy - HashPtrTable(const HashPtrTable&); + HashPtrTable(const HashPtrTable& ht); //- Destructor @@ -113,10 +113,10 @@ public: // Edit //- Remove and return the pointer specified by given iterator - T* remove(iterator&); + T* remove(iterator& iter); //- Erase an hashedEntry specified by given iterator - bool erase(iterator&); + bool erase(iterator& iter); //- Clear all entries from table void clear(); @@ -127,7 +127,8 @@ public: // Member Operators - void operator=(const HashPtrTable&); + //- Copy assignment + void operator=(const HashPtrTable& rhs); // IOstream Operators diff --git a/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTableIO.C b/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTableIO.C index 283968a9b4..ddd10aea4c 100644 --- a/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTableIO.C +++ b/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTableIO.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -61,7 +61,7 @@ void Foam::HashPtrTable::read(Istream& is, const INew& inewt) if (delimiter == token::BEGIN_LIST) { - for (label i=0; i> key; @@ -166,8 +166,11 @@ void Foam::HashPtrTable::write(Ostream& os) const ++iter ) { - const T* ptr = iter(); - ptr->write(os); + const T* ptr = *iter; + if (ptr) + { + ptr->write(os); + } } } @@ -226,7 +229,14 @@ Foam::Ostream& Foam::operator<< ++iter ) { - os << iter.key() << token::SPACE << *iter() << nl; + const T* ptr = *iter; + + os << iter.key(); + if (ptr) + { + os << token::SPACE << *ptr; + } + os << nl; } // Write end delimiter