diff options
author | David Crocker <dcrocker@eschertech.com> | 2022-04-25 11:23:18 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2022-04-25 11:23:18 +0300 |
commit | c929e2fde6cbdf102c17339ab3f374ed39190186 (patch) | |
tree | f532ebf29dbdee274914f0d839be252f3e2a1773 | |
parent | d1bd8e369480cb2de9ca3c9d91fa8ee4bb7b6093 (diff) |
Bug fix for indexing into arrays represented as bitmaps in OM
-rw-r--r-- | src/ObjectModel/ObjectModel.cpp | 99 | ||||
-rw-r--r-- | src/Version.h | 2 |
2 files changed, 66 insertions, 35 deletions
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<uint32_t>::MakeFromRaw(val.uVal).CountSetBits(); + if (context.WantArrayLength()) { - break; - } - const auto bm = Bitmap<uint32_t>::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<uint32_t>::MakeFromRaw(val.uVal).GetSetBitNumber(context.GetLastIndex()))); } - const auto bm = Bitmap<uint32_t>::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<uint64_t>::MakeFromRaw(val.Get56BitValue()).CountSetBits(); + if (context.WantArrayLength()) { - break; - } - const auto bm = Bitmap<uint64_t>::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<uint64_t>::MakeFromRaw(val.Get56BitValue()).GetSetBitNumber(context.GetLastIndex()))); } - const auto bm = Bitmap<uint64_t>::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 |