From 2183bb410fa9f9f37ac1f41ee9a2c90244aa562a Mon Sep 17 00:00:00 2001 From: paxcut Date: Sun, 12 Apr 2026 13:54:52 -0700 Subject: [PATCH 1/4] fix: Detection of having reached the end of file was not done correctly. All changes revolve around the fact that the last address of any input file is baseAddress + fileSize - 1 when size > 0 and baseAddress when size == 0 --- .../core/ast/ast_node_array_variable_decl.cpp | 78 ++++++++++++++----- .../ast_node_bitfield_array_variable_decl.cpp | 11 ++- .../ast/ast_node_pointer_variable_decl.cpp | 7 +- .../pl/core/ast/ast_node_variable_decl.cpp | 7 +- 4 files changed, 77 insertions(+), 26 deletions(-) diff --git a/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp index afd1fc8a..7719dd1a 100644 --- a/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp @@ -71,7 +71,12 @@ namespace pl::core::ast { [](auto &&offset) -> u64 { return u64(offset); } }, offset->getValue())); - if (evaluator->getReadOffset() < evaluator->getDataBaseAddress() || evaluator->getReadOffset() > evaluator->getDataBaseAddress() + evaluator->getDataSize()) + u64 size = evaluator->getDataSize(); + u64 baseAddress = evaluator->getDataBaseAddress(); + u64 maxAddress = baseAddress + size; + if (size > 0) + maxAddress = maxAddress - 1; + if (evaluator->getReadOffset() < baseAddress || evaluator->getReadOffset() > maxAddress) err::E0005.throwError(fmt::format("Cannot place variable '{}' at out of bounds address 0x{:08X}", this->m_name, evaluator->getReadOffset()), { }, this->getLocation()); } @@ -183,10 +188,15 @@ namespace pl::core::ast { }, literal->getValue()); } else if (auto whileStatement = dynamic_cast(sizeNode.get())) { while (whileStatement->evaluateCondition(evaluator)) { - if (templatePattern->getSection() == ptrn::Pattern::MainSectionId) - if ((evaluator->getReadOffset() - evaluator->getDataBaseAddress()) > (evaluator->getDataSize() + 1)) - err::E0004.throwError("Array expanded past end of the data before termination condition was met.", { }, this->getLocation()); - + if (templatePattern->getSection() == ptrn::Pattern::MainSectionId) { + u64 size = evaluator->getDataSize(); + u64 baseAddress = evaluator->getDataBaseAddress(); + u64 maxAddress = baseAddress + size; + if (size > 0) + maxAddress = maxAddress - 1; + if (evaluator->getReadOffset() > maxAddress) + err::E0004.throwError("Array expanded past end of the data before termination condition was met.", {}, this->getLocation()); + } evaluator->handleAbort(); entryCount++; evaluator->getReadOffsetAndIncrement(templatePattern->getSize()); @@ -198,10 +208,15 @@ namespace pl::core::ast { } else { std::vector buffer(templatePattern->getSize()); while (true) { - if (templatePattern->getSection() == ptrn::Pattern::MainSectionId) - if ((evaluator->getReadOffset() - evaluator->getDataBaseAddress()) > (evaluator->getDataSize() + 1)) + if (templatePattern->getSection() == ptrn::Pattern::MainSectionId) { + u64 dataSize = evaluator->getDataSize(); + u64 baseAddress = evaluator->getDataBaseAddress(); + u64 maxAddress = baseAddress + dataSize; + if (dataSize > 0) + maxAddress = maxAddress - 1; + if (evaluator->getReadOffset() > maxAddress) err::E0004.throwError("Array expanded past end of the data before a null-entry was found.", "Try using a while-sized array instead to limit the size of the array.", this->getLocation()); - + } evaluator->readData(evaluator->getReadOffset(), buffer.data(), buffer.size(), templatePattern->getSection()); evaluator->getReadOffsetAndIncrement(buffer.size()); @@ -245,9 +260,15 @@ namespace pl::core::ast { evaluator->setReadOffset(startOffset + outputPattern->getSize()); - if (outputPattern->getSection() == ptrn::Pattern::MainSectionId) - if ((evaluator->getReadOffset() - evaluator->getDataBaseAddress()) > (evaluator->getDataSize() + 1)) - err::E0004.throwError("Array expanded past end of the data.", { }, this->getLocation()); + if (outputPattern->getSection() == ptrn::Pattern::MainSectionId) { + u64 size = evaluator->getDataSize(); + u64 baseAddress = evaluator->getDataBaseAddress(); + u64 maxAddress = baseAddress + size; + if (size > 0) + maxAddress = maxAddress - 1; + if (evaluator->getReadOffset() > maxAddress) + err::E0004.throwError("Array expanded past end of the data.", {}, this->getLocation()); + } } void ASTNodeArrayVariableDecl::createDynamicArray(Evaluator *evaluator, std::shared_ptr &resultPattern) const { @@ -326,10 +347,15 @@ namespace pl::core::ast { this->m_type->createPatterns(evaluator, patterns); size_t patternCount = patterns.size(); - if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) - if ((evaluator->getReadOffset() - evaluator->getDataBaseAddress()) > (evaluator->getDataSize() + 1)) + if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) { + u64 dataSize = evaluator->getDataSize(); + u64 baseAddress = evaluator->getDataBaseAddress(); + u64 maxAddress = baseAddress + dataSize; + if (dataSize > 0) + maxAddress = maxAddress - 1; + if (evaluator->getReadOffset() > maxAddress) err::E0004.throwError("Array expanded past end of the data.", fmt::format("Entry {} exceeded data by {} bytes.", i, evaluator->getReadOffset() - evaluator->getDataSize()), this->getLocation()); - + } if (!patterns.empty()) addEntries(std::move(patterns)); @@ -359,10 +385,15 @@ namespace pl::core::ast { this->m_type->createPatterns(evaluator, patterns); size_t patternCount = patterns.size(); - if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) - if ((evaluator->getReadOffset() - evaluator->getDataBaseAddress()) > (evaluator->getDataSize() + 1)) - err::E0004.throwError("Array expanded past end of the data before termination condition was met.", { }, this->getLocation()); - + if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) { + u64 dataSize = evaluator->getDataSize(); + u64 baseAddress = evaluator->getDataBaseAddress(); + u64 maxAddress = baseAddress + dataSize; + if (dataSize > 0) + maxAddress = maxAddress - 1; + if (evaluator->getReadOffset() > maxAddress) + err::E0004.throwError("Array expanded past end of the data before termination condition was met.", {}, this->getLocation()); + } if (!patterns.empty()) addEntries(std::move(patterns)); @@ -397,10 +428,15 @@ namespace pl::core::ast { for (auto &pattern : patterns) { std::vector buffer(pattern->getSize()); - if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) - if ((evaluator->getReadOffset() - evaluator->getDataBaseAddress()) > (evaluator->getDataSize() + 1)) + if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) { + u64 dataSize = evaluator->getDataSize(); + u64 baseAddress = evaluator->getDataBaseAddress(); + u64 maxAddress = baseAddress + dataSize; + if (dataSize > 0) + maxAddress = maxAddress - 1; + if (evaluator->getReadOffset() > maxAddress) err::E0004.throwError("Array expanded past end of the data before a null-entry was found.", "Try using a while-sized array instead to limit the size of the array.", this->getLocation()); - + } const auto patternSize = pattern->getSize(); evaluator->readData(evaluator->getReadOffset() - patternSize, buffer.data(), buffer.size(), pattern->getSection()); diff --git a/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp index 7bc284bb..c520b971 100644 --- a/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp @@ -149,10 +149,15 @@ namespace pl::core::ast { std::vector> patterns; this->m_type->createPatterns(evaluator, patterns); - if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) - if ((evaluator->getReadOffset() - evaluator->getDataBaseAddress()) > (evaluator->getDataSize() + 1)) + if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) { + u64 dataSize = evaluator->getDataSize(); + u64 baseAddress = evaluator->getDataBaseAddress(); + u64 maxAddress = baseAddress + dataSize; + if (dataSize > 0) + maxAddress = maxAddress - 1; + if (evaluator->getReadOffset() > maxAddress) err::E0004.throwError("Bitfield array expanded past end of the data.", fmt::format("Entry {} exceeded data by {} bytes.", dataIndex, evaluator->getReadOffset() - evaluator->getDataSize()), this->getLocation()); - + } auto ctrlFlow = evaluator->getCurrentControlFlowStatement(); evaluator->setCurrentControlFlowStatement(ControlFlowStatement::None); diff --git a/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp index ece5c443..aabd3bf7 100644 --- a/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp @@ -58,7 +58,12 @@ namespace pl::core::ast { [](auto &&offset) -> u64 { return u64(offset); } }, offset->getValue())); - if (evaluator->getReadOffset() < evaluator->getDataBaseAddress() || evaluator->getReadOffset() > evaluator->getDataBaseAddress() + evaluator->getDataSize()) + u64 size = evaluator->getDataSize(); + u64 baseAddress = evaluator->getDataBaseAddress(); + u64 maxAddress = baseAddress + size; + if (size > 0) + maxAddress = maxAddress - 1; + if (evaluator->getReadOffset() < baseAddress || evaluator->getReadOffset() > maxAddress) err::E0005.throwError(fmt::format("Cannot place variable '{}' at out of bounds address 0x{:08X}", this->m_name, evaluator->getReadOffset()), { }, this->getLocation()); } diff --git a/lib/source/pl/core/ast/ast_node_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_variable_decl.cpp index 4fb3d2b4..ec0f90d1 100644 --- a/lib/source/pl/core/ast/ast_node_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_variable_decl.cpp @@ -59,7 +59,12 @@ namespace pl::core::ast { [](auto &&offset) -> u64 { return u64(offset); } }, offset->getValue())); - if (evaluator->getReadOffset() < evaluator->getDataBaseAddress() || evaluator->getReadOffset() > evaluator->getDataBaseAddress() + evaluator->getDataSize()) + u64 size = evaluator->getDataSize(); + u64 baseAddress = evaluator->getDataBaseAddress(); + u64 maxAddress = baseAddress + size; + if (size > 0) + maxAddress = maxAddress - 1; + if (evaluator->getReadOffset() < baseAddress || evaluator->getReadOffset() > maxAddress) err::E0005.throwError(fmt::format("Cannot place variable '{}' at out of bounds address 0x{:08X}", this->m_name, evaluator->getReadOffset()), { }, this->getLocation()); } From 934c51d5435f13e9a326ad3d3f067478cc386188 Mon Sep 17 00:00:00 2001 From: paxcut Date: Sun, 12 Apr 2026 23:50:29 -0700 Subject: [PATCH 2/4] Adjust past eof check to occur in the byte after the input file's last. --- .../pl/core/ast/ast_node_array_variable_decl.cpp | 12 ------------ .../ast/ast_node_bitfield_array_variable_decl.cpp | 2 -- 2 files changed, 14 deletions(-) diff --git a/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp index 7719dd1a..d44b90cd 100644 --- a/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp @@ -192,8 +192,6 @@ namespace pl::core::ast { u64 size = evaluator->getDataSize(); u64 baseAddress = evaluator->getDataBaseAddress(); u64 maxAddress = baseAddress + size; - if (size > 0) - maxAddress = maxAddress - 1; if (evaluator->getReadOffset() > maxAddress) err::E0004.throwError("Array expanded past end of the data before termination condition was met.", {}, this->getLocation()); } @@ -212,8 +210,6 @@ namespace pl::core::ast { u64 dataSize = evaluator->getDataSize(); u64 baseAddress = evaluator->getDataBaseAddress(); u64 maxAddress = baseAddress + dataSize; - if (dataSize > 0) - maxAddress = maxAddress - 1; if (evaluator->getReadOffset() > maxAddress) err::E0004.throwError("Array expanded past end of the data before a null-entry was found.", "Try using a while-sized array instead to limit the size of the array.", this->getLocation()); } @@ -264,8 +260,6 @@ namespace pl::core::ast { u64 size = evaluator->getDataSize(); u64 baseAddress = evaluator->getDataBaseAddress(); u64 maxAddress = baseAddress + size; - if (size > 0) - maxAddress = maxAddress - 1; if (evaluator->getReadOffset() > maxAddress) err::E0004.throwError("Array expanded past end of the data.", {}, this->getLocation()); } @@ -351,8 +345,6 @@ namespace pl::core::ast { u64 dataSize = evaluator->getDataSize(); u64 baseAddress = evaluator->getDataBaseAddress(); u64 maxAddress = baseAddress + dataSize; - if (dataSize > 0) - maxAddress = maxAddress - 1; if (evaluator->getReadOffset() > maxAddress) err::E0004.throwError("Array expanded past end of the data.", fmt::format("Entry {} exceeded data by {} bytes.", i, evaluator->getReadOffset() - evaluator->getDataSize()), this->getLocation()); } @@ -389,8 +381,6 @@ namespace pl::core::ast { u64 dataSize = evaluator->getDataSize(); u64 baseAddress = evaluator->getDataBaseAddress(); u64 maxAddress = baseAddress + dataSize; - if (dataSize > 0) - maxAddress = maxAddress - 1; if (evaluator->getReadOffset() > maxAddress) err::E0004.throwError("Array expanded past end of the data before termination condition was met.", {}, this->getLocation()); } @@ -432,8 +422,6 @@ namespace pl::core::ast { u64 dataSize = evaluator->getDataSize(); u64 baseAddress = evaluator->getDataBaseAddress(); u64 maxAddress = baseAddress + dataSize; - if (dataSize > 0) - maxAddress = maxAddress - 1; if (evaluator->getReadOffset() > maxAddress) err::E0004.throwError("Array expanded past end of the data before a null-entry was found.", "Try using a while-sized array instead to limit the size of the array.", this->getLocation()); } diff --git a/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp index c520b971..a31beba5 100644 --- a/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp @@ -153,8 +153,6 @@ namespace pl::core::ast { u64 dataSize = evaluator->getDataSize(); u64 baseAddress = evaluator->getDataBaseAddress(); u64 maxAddress = baseAddress + dataSize; - if (dataSize > 0) - maxAddress = maxAddress - 1; if (evaluator->getReadOffset() > maxAddress) err::E0004.throwError("Bitfield array expanded past end of the data.", fmt::format("Entry {} exceeded data by {} bytes.", dataIndex, evaluator->getReadOffset() - evaluator->getDataSize()), this->getLocation()); } From 61f6be23f8aecbcfd56dd619b94d97ab5b5392c8 Mon Sep 17 00:00:00 2001 From: paxcut Date: Mon, 13 Apr 2026 00:34:39 -0700 Subject: [PATCH 3/4] Adjust past eof check to occur in the byte after the input file's last. --- lib/source/pl/core/ast/ast_node_array_variable_decl.cpp | 2 -- lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp | 2 -- lib/source/pl/core/ast/ast_node_variable_decl.cpp | 2 -- 3 files changed, 6 deletions(-) diff --git a/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp index d44b90cd..1db04510 100644 --- a/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp @@ -74,8 +74,6 @@ namespace pl::core::ast { u64 size = evaluator->getDataSize(); u64 baseAddress = evaluator->getDataBaseAddress(); u64 maxAddress = baseAddress + size; - if (size > 0) - maxAddress = maxAddress - 1; if (evaluator->getReadOffset() < baseAddress || evaluator->getReadOffset() > maxAddress) err::E0005.throwError(fmt::format("Cannot place variable '{}' at out of bounds address 0x{:08X}", this->m_name, evaluator->getReadOffset()), { }, this->getLocation()); } diff --git a/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp index aabd3bf7..1b4b846b 100644 --- a/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp @@ -61,8 +61,6 @@ namespace pl::core::ast { u64 size = evaluator->getDataSize(); u64 baseAddress = evaluator->getDataBaseAddress(); u64 maxAddress = baseAddress + size; - if (size > 0) - maxAddress = maxAddress - 1; if (evaluator->getReadOffset() < baseAddress || evaluator->getReadOffset() > maxAddress) err::E0005.throwError(fmt::format("Cannot place variable '{}' at out of bounds address 0x{:08X}", this->m_name, evaluator->getReadOffset()), { }, this->getLocation()); } diff --git a/lib/source/pl/core/ast/ast_node_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_variable_decl.cpp index ec0f90d1..f8a6a1c6 100644 --- a/lib/source/pl/core/ast/ast_node_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_variable_decl.cpp @@ -62,8 +62,6 @@ namespace pl::core::ast { u64 size = evaluator->getDataSize(); u64 baseAddress = evaluator->getDataBaseAddress(); u64 maxAddress = baseAddress + size; - if (size > 0) - maxAddress = maxAddress - 1; if (evaluator->getReadOffset() < baseAddress || evaluator->getReadOffset() > maxAddress) err::E0005.throwError(fmt::format("Cannot place variable '{}' at out of bounds address 0x{:08X}", this->m_name, evaluator->getReadOffset()), { }, this->getLocation()); } From 675bd6c9b66b4ee51f0d1b18f356eebeefece690 Mon Sep 17 00:00:00 2001 From: paxcut Date: Mon, 13 Apr 2026 04:22:27 -0700 Subject: [PATCH 4/4] Reverted unnecessary changes and rewrote for efficiency (no storage) --- .../core/ast/ast_node_array_variable_decl.cpp | 64 ++++++------------- .../ast_node_bitfield_array_variable_decl.cpp | 9 +-- .../ast/ast_node_pointer_variable_decl.cpp | 5 +- .../pl/core/ast/ast_node_variable_decl.cpp | 5 +- 4 files changed, 26 insertions(+), 57 deletions(-) diff --git a/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp index 1db04510..ebc4b70c 100644 --- a/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_array_variable_decl.cpp @@ -71,10 +71,7 @@ namespace pl::core::ast { [](auto &&offset) -> u64 { return u64(offset); } }, offset->getValue())); - u64 size = evaluator->getDataSize(); - u64 baseAddress = evaluator->getDataBaseAddress(); - u64 maxAddress = baseAddress + size; - if (evaluator->getReadOffset() < baseAddress || evaluator->getReadOffset() > maxAddress) + if (evaluator->getReadOffset() < evaluator->getDataBaseAddress() || evaluator->getReadOffset() > evaluator->getDataBaseAddress() + evaluator->getDataSize()) err::E0005.throwError(fmt::format("Cannot place variable '{}' at out of bounds address 0x{:08X}", this->m_name, evaluator->getReadOffset()), { }, this->getLocation()); } @@ -186,13 +183,10 @@ namespace pl::core::ast { }, literal->getValue()); } else if (auto whileStatement = dynamic_cast(sizeNode.get())) { while (whileStatement->evaluateCondition(evaluator)) { - if (templatePattern->getSection() == ptrn::Pattern::MainSectionId) { - u64 size = evaluator->getDataSize(); - u64 baseAddress = evaluator->getDataBaseAddress(); - u64 maxAddress = baseAddress + size; - if (evaluator->getReadOffset() > maxAddress) - err::E0004.throwError("Array expanded past end of the data before termination condition was met.", {}, this->getLocation()); - } + if (templatePattern->getSection() == ptrn::Pattern::MainSectionId) + if ((evaluator->getReadOffset() - evaluator->getDataBaseAddress()) > (evaluator->getDataSize())) + err::E0004.throwError("Array expanded past end of the data before termination condition was met.", { }, this->getLocation()); + evaluator->handleAbort(); entryCount++; evaluator->getReadOffsetAndIncrement(templatePattern->getSize()); @@ -204,13 +198,10 @@ namespace pl::core::ast { } else { std::vector buffer(templatePattern->getSize()); while (true) { - if (templatePattern->getSection() == ptrn::Pattern::MainSectionId) { - u64 dataSize = evaluator->getDataSize(); - u64 baseAddress = evaluator->getDataBaseAddress(); - u64 maxAddress = baseAddress + dataSize; - if (evaluator->getReadOffset() > maxAddress) + if (templatePattern->getSection() == ptrn::Pattern::MainSectionId) + if ((evaluator->getReadOffset() - evaluator->getDataBaseAddress()) > (evaluator->getDataSize())) err::E0004.throwError("Array expanded past end of the data before a null-entry was found.", "Try using a while-sized array instead to limit the size of the array.", this->getLocation()); - } + evaluator->readData(evaluator->getReadOffset(), buffer.data(), buffer.size(), templatePattern->getSection()); evaluator->getReadOffsetAndIncrement(buffer.size()); @@ -254,13 +245,9 @@ namespace pl::core::ast { evaluator->setReadOffset(startOffset + outputPattern->getSize()); - if (outputPattern->getSection() == ptrn::Pattern::MainSectionId) { - u64 size = evaluator->getDataSize(); - u64 baseAddress = evaluator->getDataBaseAddress(); - u64 maxAddress = baseAddress + size; - if (evaluator->getReadOffset() > maxAddress) - err::E0004.throwError("Array expanded past end of the data.", {}, this->getLocation()); - } + if (outputPattern->getSection() == ptrn::Pattern::MainSectionId) + if ((evaluator->getReadOffset() - evaluator->getDataBaseAddress()) > (evaluator->getDataSize())) + err::E0004.throwError("Array expanded past end of the data.", { }, this->getLocation()); } void ASTNodeArrayVariableDecl::createDynamicArray(Evaluator *evaluator, std::shared_ptr &resultPattern) const { @@ -339,13 +326,10 @@ namespace pl::core::ast { this->m_type->createPatterns(evaluator, patterns); size_t patternCount = patterns.size(); - if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) { - u64 dataSize = evaluator->getDataSize(); - u64 baseAddress = evaluator->getDataBaseAddress(); - u64 maxAddress = baseAddress + dataSize; - if (evaluator->getReadOffset() > maxAddress) + if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) + if ((evaluator->getReadOffset() - evaluator->getDataBaseAddress()) > (evaluator->getDataSize())) err::E0004.throwError("Array expanded past end of the data.", fmt::format("Entry {} exceeded data by {} bytes.", i, evaluator->getReadOffset() - evaluator->getDataSize()), this->getLocation()); - } + if (!patterns.empty()) addEntries(std::move(patterns)); @@ -375,13 +359,10 @@ namespace pl::core::ast { this->m_type->createPatterns(evaluator, patterns); size_t patternCount = patterns.size(); - if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) { - u64 dataSize = evaluator->getDataSize(); - u64 baseAddress = evaluator->getDataBaseAddress(); - u64 maxAddress = baseAddress + dataSize; - if (evaluator->getReadOffset() > maxAddress) - err::E0004.throwError("Array expanded past end of the data before termination condition was met.", {}, this->getLocation()); - } + if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) + if ((evaluator->getReadOffset() - evaluator->getDataBaseAddress()) > (evaluator->getDataSize())) + err::E0004.throwError("Array expanded past end of the data before termination condition was met.", { }, this->getLocation()); + if (!patterns.empty()) addEntries(std::move(patterns)); @@ -416,13 +397,10 @@ namespace pl::core::ast { for (auto &pattern : patterns) { std::vector buffer(pattern->getSize()); - if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) { - u64 dataSize = evaluator->getDataSize(); - u64 baseAddress = evaluator->getDataBaseAddress(); - u64 maxAddress = baseAddress + dataSize; - if (evaluator->getReadOffset() > maxAddress) + if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) + if ((evaluator->getReadOffset() - evaluator->getDataBaseAddress()) > (evaluator->getDataSize())) err::E0004.throwError("Array expanded past end of the data before a null-entry was found.", "Try using a while-sized array instead to limit the size of the array.", this->getLocation()); - } + const auto patternSize = pattern->getSize(); evaluator->readData(evaluator->getReadOffset() - patternSize, buffer.data(), buffer.size(), pattern->getSection()); diff --git a/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp index a31beba5..b7622fa8 100644 --- a/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp @@ -149,13 +149,10 @@ namespace pl::core::ast { std::vector> patterns; this->m_type->createPatterns(evaluator, patterns); - if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) { - u64 dataSize = evaluator->getDataSize(); - u64 baseAddress = evaluator->getDataBaseAddress(); - u64 maxAddress = baseAddress + dataSize; - if (evaluator->getReadOffset() > maxAddress) + if (arrayPattern->getSection() == ptrn::Pattern::MainSectionId) + if ((evaluator->getReadOffset() - evaluator->getDataBaseAddress()) > (evaluator->getDataSize())) err::E0004.throwError("Bitfield array expanded past end of the data.", fmt::format("Entry {} exceeded data by {} bytes.", dataIndex, evaluator->getReadOffset() - evaluator->getDataSize()), this->getLocation()); - } + auto ctrlFlow = evaluator->getCurrentControlFlowStatement(); evaluator->setCurrentControlFlowStatement(ControlFlowStatement::None); diff --git a/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp index 1b4b846b..ece5c443 100644 --- a/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_pointer_variable_decl.cpp @@ -58,10 +58,7 @@ namespace pl::core::ast { [](auto &&offset) -> u64 { return u64(offset); } }, offset->getValue())); - u64 size = evaluator->getDataSize(); - u64 baseAddress = evaluator->getDataBaseAddress(); - u64 maxAddress = baseAddress + size; - if (evaluator->getReadOffset() < baseAddress || evaluator->getReadOffset() > maxAddress) + if (evaluator->getReadOffset() < evaluator->getDataBaseAddress() || evaluator->getReadOffset() > evaluator->getDataBaseAddress() + evaluator->getDataSize()) err::E0005.throwError(fmt::format("Cannot place variable '{}' at out of bounds address 0x{:08X}", this->m_name, evaluator->getReadOffset()), { }, this->getLocation()); } diff --git a/lib/source/pl/core/ast/ast_node_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_variable_decl.cpp index f8a6a1c6..4fb3d2b4 100644 --- a/lib/source/pl/core/ast/ast_node_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_variable_decl.cpp @@ -59,10 +59,7 @@ namespace pl::core::ast { [](auto &&offset) -> u64 { return u64(offset); } }, offset->getValue())); - u64 size = evaluator->getDataSize(); - u64 baseAddress = evaluator->getDataBaseAddress(); - u64 maxAddress = baseAddress + size; - if (evaluator->getReadOffset() < baseAddress || evaluator->getReadOffset() > maxAddress) + if (evaluator->getReadOffset() < evaluator->getDataBaseAddress() || evaluator->getReadOffset() > evaluator->getDataBaseAddress() + evaluator->getDataSize()) err::E0005.throwError(fmt::format("Cannot place variable '{}' at out of bounds address 0x{:08X}", this->m_name, evaluator->getReadOffset()), { }, this->getLocation()); }