Skip to content
This repository has been archived by the owner on Sep 1, 2022. It is now read-only.

Commit

Permalink
fix integer underflow that occured when certain non-existent points w…
Browse files Browse the repository at this point in the history
…ere updated in discontiguous index mode
  • Loading branch information
jadamcrain committed Sep 22, 2017
1 parent c8c7d54 commit 827cb6d
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 36 deletions.
69 changes: 33 additions & 36 deletions cpp/libs/src/opendnp3/outstation/IndexSearch.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,54 +117,51 @@ IndexSearch::Result IndexSearch::FindClosestRawIndex(const openpal::ArrayView<Ce
{
return Result(false, 0);
}
else

uint16_t lower = 0;
uint16_t upper = view.Size() - 1;

uint16_t midpoint = 0;

while (lower <= upper)
{
uint16_t lower = 0;
uint16_t upper = view.Size() - 1;
midpoint = GetMidpoint(lower, upper);

uint16_t midpoint = 0;
const auto index = view[midpoint].config.vIndex;

while (lower <= upper)
if (index == vIndex)
{
midpoint = GetMidpoint(lower, upper);

auto index = view[midpoint].config.vIndex;
// exact match
return Result(true, midpoint);
}

if (index == vIndex)
if (index < vIndex) // search the upper array
{
if (lower < openpal::MaxValue<uint16_t>())
{
return Result(true, midpoint);
lower = midpoint + 1;
}
else
{
if (index < vIndex) // search the upper array
{
if (lower < openpal::MaxValue<uint16_t>())
{
lower = midpoint + 1;
}
else
{
//we're at the upper limit
return Result(false, midpoint);
}
}
else
{
if (upper > 0)
{
upper = midpoint - 1;
}
else
{
//we're at the lower limit
return Result(false, midpoint);
}
}
//we're at the upper limit
return Result(false, midpoint);
}
}
else // search the lower array
{
if (upper > 0 && midpoint > 0)
{
upper = midpoint - 1;
}
else
{
//we're at the lower limit
return Result(false, midpoint);
}
}

return Result(false, midpoint);
}

return Result(false, midpoint);
}

}
Expand Down
22 changes: 22 additions & 0 deletions cpp/tests/opendnp3/src/TestOutstation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,28 @@ TEST_CASE(SUITE("ContiguousIndexesInDiscontiguousModeIntegrityScan"))
REQUIRE(t.lower->PopWriteAsHex() == "C0 81 80 00 01 02 00 00 01 02 02");
}

TEST_CASE(SUITE("can safely update non-existent index in discontiguous index mode"))
{
OutstationConfig config;
config.params.indexMode = IndexMode::Discontiguous;
OutstationTestObject t(config, DatabaseSizes::BinaryOnly(2));

auto view = t.context.GetConfigView();
for (int i = 0; i < 2; ++i)
{
view.binaries[i].config.clazz = PointClass::Class1;
view.binaries[i].config.svariation = StaticBinaryVariation::Group1Var2;
view.binaries[i].config.evariation = EventBinaryVariation::Group2Var3;
view.binaries[i].config.vIndex = i + 2;
}

// now send an update to boundary points that doesn't exist
REQUIRE_FALSE(t.context.GetUpdateHandler().Update(Binary(true), 0, EventMode::Suppress));
REQUIRE_FALSE(t.context.GetUpdateHandler().Update(Binary(true), 1, EventMode::Suppress));
// 2 & 3 exist
REQUIRE_FALSE(t.context.GetUpdateHandler().Update(Binary(true), 4, EventMode::Suppress));
}

TEST_CASE(SUITE("ContiguousIndexesInDiscontiguousModeRangeScan"))
{
// this will tell the outstation to use discontiguous index mode, but we won't change the address assignments
Expand Down

0 comments on commit 827cb6d

Please sign in to comment.