From 324b17a813cc7f9afe80728c881b80bd46b645b8 Mon Sep 17 00:00:00 2001 From: Marek Otahal Date: Fri, 12 Jan 2018 02:52:00 +0100 Subject: [PATCH 1/2] SP: WIP add check for sizes of in/out arrays in compute() these fields are entered by user and must exactly match the Input, Columns sizes. Unfortunately, the array is passed as T* so getting the size will be tricky. --- src/nupic/algorithms/SpatialPooler.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/nupic/algorithms/SpatialPooler.cpp b/src/nupic/algorithms/SpatialPooler.cpp index bd8b366173..4c8f131b36 100644 --- a/src/nupic/algorithms/SpatialPooler.cpp +++ b/src/nupic/algorithms/SpatialPooler.cpp @@ -598,6 +598,11 @@ void SpatialPooler::initialize(vector inputDimensions, void SpatialPooler::compute(UInt inputArray[], bool learn, UInt activeArray[]) { + // check size of input/output arrays + //TODO since c++17 there is std::size() in for arrays +// NTA_ASSERT(this->getNumInputs() == std::vector(inputArray).size()); //FIXME get size of the array (T*) ? +// NTA_ASSERT(this->getNumColumns() == sizeof(*activeArray)/sizeof(UInt)); + updateBookeepingVars_(learn); calculateOverlap_(inputArray, overlaps_); calculateOverlapPct_(overlaps_, overlapsPct_); From 84ae3d728a7cbc620781a5bb4285db0b156def95 Mon Sep 17 00:00:00 2001 From: Marek Otahal Date: Fri, 12 Jan 2018 03:16:27 +0100 Subject: [PATCH 2/2] SP: add test for invalid array sizes for compute() --- .../unit/algorithms/SpatialPoolerTest.cpp | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/unit/algorithms/SpatialPoolerTest.cpp b/src/test/unit/algorithms/SpatialPoolerTest.cpp index 88f3882a2e..5778c4b646 100644 --- a/src/test/unit/algorithms/SpatialPoolerTest.cpp +++ b/src/test/unit/algorithms/SpatialPoolerTest.cpp @@ -2222,6 +2222,27 @@ namespace { EXPECT_EQ(0, countNonzero(activeColumns)); } + + TEST(SpatialPoolerTest, testComputeWrongInput) + { + /** this test checks behavior when user passes arrays of incorrect + size to the compute() */ + SpatialPooler sp{std::vector{5} /* input*/, std::vector{10}/* SP output cols */}; + std::vector inputOK = {1, 2, 3, 4, 5}; //true size is 5 + std::vector inputFail = {1,2}; + + + std::vector outOK(sp.getNumColumns(), 0); //true size is 10 + std::vector outFail(4, 0); //fails size is 4 < 10, this could write to other data memory -> crash + std::vector outFailButNoFail(100, 0); //wrong size, but 100>10 so no address space violation (just wasteful), should pass + + EXPECT_NO_THROW(sp.compute(inputOK.data(), true, outOK.data())); +//FIXME EXPECT_ANY does not handle the malloc fail caused here, crashes! +//! EXPECT_ANY_THROW(sp.compute(inputFail.data(), true, outOK.data())); +//! EXPECT_ANY_THROW(sp.compute(inputOK.data(), true, outFail.data())); + EXPECT_NO_THROW(sp.compute(inputOK.data(), true, outFailButNoFail.data())); +} + TEST(SpatialPoolerTest, testSaveLoad) { const char* filename = "SpatialPoolerSerialization.tmp";