From c929e2fde6cbdf102c17339ab3f374ed39190186 Mon Sep 17 00:00:00 2001 From: David Crocker Date: Mon, 25 Apr 2022 09:23:18 +0100 Subject: Bug fix for indexing into arrays represented as bitmaps in OM --- src/ObjectModel/ObjectModel.cpp | 99 +++++++++++++++++++++++++++-------------- src/Version.h | 2 +- 2 files changed, 66 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/ObjectModel/ObjectModel.cpp b/src/ObjectModel/ObjectModel.cpp index bef41e8f..215c7414 100644 --- a/src/ObjectModel/ObjectModel.cpp +++ b/src/ObjectModel/ObjectModel.cpp @@ -1042,29 +1042,44 @@ decrease(strlen(idString)) // recursion variant case TypeCode::Bitmap16: case TypeCode::Bitmap32: - if (context.WantArrayLength()) { - if (*idString != 0) + const int numSetBits = Bitmap::MakeFromRaw(val.uVal).CountSetBits(); + if (context.WantArrayLength()) { - break; - } - const auto bm = Bitmap::MakeFromRaw(val.uVal); - return ExpressionValue((int32_t)bm.CountSetBits()); - } - if (*idString == '^') - { - ++idString; - if (*idString != 0) - { - break; + if (*idString != 0) + { + break; + } + return ExpressionValue((int32_t)numSetBits); } - if (context.WantExists()) + + if (*idString == '^') { - return ExpressionValue(true); + ++idString; + if (*idString != 0) + { + break; + } + context.AddIndex(); + const bool inBounds = (context.GetLastIndex() >= 0 && context.GetLastIndex() < numSetBits); + if (context.WantExists()) + { + return ExpressionValue(inBounds); + } + + if (!inBounds) + { + throw context.ConstructParseException("array index out of bounds"); + } + + if (context.WantExists()) + { + return ExpressionValue(true); + } + return ExpressionValue((int32_t)(Bitmap::MakeFromRaw(val.uVal).GetSetBitNumber(context.GetLastIndex()))); } - const auto bm = Bitmap::MakeFromRaw(val.uVal); - return ExpressionValue((int32_t)bm.GetSetBitNumber(context.GetLastIndex())); } + if (*idString != 0) { break; @@ -1076,29 +1091,45 @@ decrease(strlen(idString)) // recursion variant return ExpressionValue((int32_t)val.uVal); case TypeCode::Bitmap64: - if (context.WantArrayLength()) { - if (*idString != 0) + const int numSetBits = Bitmap::MakeFromRaw(val.Get56BitValue()).CountSetBits(); + if (context.WantArrayLength()) { - break; - } - const auto bm = Bitmap::MakeFromRaw(val.Get56BitValue()); - return ExpressionValue((int32_t)bm.CountSetBits()); - } - if (*idString == '^') - { - ++idString; - if (*idString != 0) - { - break; + if (*idString != 0) + { + break; + } + return ExpressionValue((int32_t)numSetBits); } - if (context.WantExists()) + + if (*idString == '^') { - return ExpressionValue(true); + ++idString; + if (*idString != 0) + { + break; + } + context.AddIndex(); + const bool inBounds = (context.GetLastIndex() >= 0 && context.GetLastIndex() < numSetBits); + if (context.WantExists()) + { + return ExpressionValue(inBounds); + } + + if (!inBounds) + { + throw context.ConstructParseException("array index out of bounds"); + } + + if (context.WantExists()) + { + return ExpressionValue(true); + } + + return ExpressionValue((int32_t)(Bitmap::MakeFromRaw(val.Get56BitValue()).GetSetBitNumber(context.GetLastIndex()))); } - const auto bm = Bitmap::MakeFromRaw(val.Get56BitValue()); - return ExpressionValue((int32_t)bm.GetSetBitNumber(context.GetLastIndex())); } + if (*idString != 0) { break; diff --git a/src/Version.h b/src/Version.h index 268bad38..474912db 100644 --- a/src/Version.h +++ b/src/Version.h @@ -10,7 +10,7 @@ #ifndef VERSION // Note: the complete VERSION string must be in standard version number format and must not contain spaces! This is so that DWC can parse it. -# define MAIN_VERSION "3.4.1beta1" +# define MAIN_VERSION "3.4.0+1" # ifdef USE_CAN0 # define VERSION_SUFFIX "(CAN0)" # else -- cgit v1.2.3