From ed0c1a1e28a4c4b0e4f45d324e246f858591bfd8 Mon Sep 17 00:00:00 2001 From: Dominik Wernberger Date: Sat, 16 Dec 2023 01:39:02 +0100 Subject: [PATCH] Add more nullptr checks --- src/CommonBase.cpp | 10 +- src/Primitives/PrimCommentText.cpp | 226 +++++++++++---------- src/Structures/StructSymbolDisplayProp.cpp | 26 ++- 3 files changed, 147 insertions(+), 115 deletions(-) diff --git a/src/CommonBase.cpp b/src/CommonBase.cpp index fb423f1..11c355c 100644 --- a/src/CommonBase.cpp +++ b/src/CommonBase.cpp @@ -351,7 +351,15 @@ std::pair CommonBase::read_single_prefix_short() const auto getStr = [&, this](uint32_t idx) -> std::string { int64_t newIdx = static_cast(idx); - return newIdx >= 0 ? gLibrary->library->strLst.at(newIdx) : ""; + if(gLibrary != nullptr) + { + if(gLibrary->library) + { + return newIdx >= 0 ? gLibrary->library->strLst.at(newIdx) : ""; + } + } + + return ""; }; spdlog::debug(" {}: {} <- {}", i, getStr(nameValueMapping.at(i).first), getStr(nameValueMapping.at(i).second)); diff --git a/src/Primitives/PrimCommentText.cpp b/src/Primitives/PrimCommentText.cpp index 871b060..1575f57 100644 --- a/src/Primitives/PrimCommentText.cpp +++ b/src/Primitives/PrimCommentText.cpp @@ -1,108 +1,120 @@ -#include -#include -#include -#include - -#include - -#include "General.hpp" -#include "Library.hpp" -#include "Primitives/PrimCommentText.hpp" -#include "Win32/LOGFONTA.hpp" - - -void PrimCommentText::read(FileFormatVersion /* aVersion */) -{ - auto& ds = mCtx.get().mDs.get(); - - spdlog::debug(getOpeningMsg(getMethodName(this, __func__), ds.getCurrentOffset())); - - const size_t startOffset = ds.getCurrentOffset(); - - // @todo Adding 8 Byte does not make any sense, why did it - // work previously and why does it work in other - // primitives that use similar data structures? - // Maybe the byte length does not count itself and - // the following 4 zero bytes. - // This issue is somehow related to the disabled - // readOptionalTrailingFuture check in StructPartInst - // and readOptionalTrailingFuture in StructT0x10 - const uint32_t byteLength = ds.readUint32() + 8U; - - ds.assumeData({0x00, 0x00, 0x00, 0x00}, getMethodName(this, __func__) + ": 0"); - - locX = ds.readInt32(); - locY = ds.readInt32(); - - spdlog::trace("locX = {}", locX); - spdlog::trace("locY = {}", locY); - - x2 = ds.readInt32(); - y2 = ds.readInt32(); - x1 = ds.readInt32(); - y1 = ds.readInt32(); - - spdlog::trace("x2 = {}", x2); - spdlog::trace("y2 = {}", y2); - spdlog::trace("x1 = {}", x1); - spdlog::trace("y1 = {}", y1); - - // @todo Check if fontIdx with 4 byte fits. I.e. are the following 2 Byte all 0? - textFontIdx = ds.readUint16(); - - spdlog::trace("textFontIdx = {}", textFontIdx); - - if(textFontIdx > gLibrary->library->textFonts.size()) - { - throw std::out_of_range(fmt::format("{}: textFontIdx is out of range! Expected {} <= {}!", - getMethodName(this, __func__), textFontIdx, gLibrary->library->textFonts.size())); - } - - ds.printUnknownData(2, getMethodName(this, __func__) + ": 1"); - - name = ds.readStringLenZeroTerm(); - - spdlog::trace("name = {}", name); - - if(ds.getCurrentOffset() != startOffset + byteLength) - { - // throw MisinterpretedData(__func__, startOffset, byteLength, ds.getCurrentOffset()); - } - - if(byteLength != 39u + name.size()) - { - // throw FileFormatChanged("CommentText"); - } - - readPreamble(); - - spdlog::debug(getClosingMsg(getMethodName(this, __func__), ds.getCurrentOffset())); - spdlog::trace(to_string()); -} - - -LOGFONTA PrimCommentText::getTextFont() const -{ - const int64_t idx = static_cast(textFontIdx) - 1; - - LOGFONTA textFont{}; - - if(idx >= 0) - { - // Retrieve font from the library. - textFont = gLibrary->library->textFonts.at(idx); - // @todo provide try catch block for better exception messages - } - else if(idx == -1) - { - // @todo Unknown but it is probably the default font; - // throw std::runtime_error(getMethodName(this, __func__) + ": Check this out!"); - } - else // idx < -1 - { - // This should never happen. - throw std::runtime_error(getMethodName(this, __func__) + ": Unexpected index " + std::to_string(idx)); - } - - return textFont; +#include +#include +#include +#include + +#include + +#include "General.hpp" +#include "Library.hpp" +#include "Primitives/PrimCommentText.hpp" +#include "Win32/LOGFONTA.hpp" + + +void PrimCommentText::read(FileFormatVersion /* aVersion */) +{ + auto& ds = mCtx.get().mDs.get(); + + spdlog::debug(getOpeningMsg(getMethodName(this, __func__), ds.getCurrentOffset())); + + const size_t startOffset = ds.getCurrentOffset(); + + // @todo Adding 8 Byte does not make any sense, why did it + // work previously and why does it work in other + // primitives that use similar data structures? + // Maybe the byte length does not count itself and + // the following 4 zero bytes. + // This issue is somehow related to the disabled + // readOptionalTrailingFuture check in StructPartInst + // and readOptionalTrailingFuture in StructT0x10 + const uint32_t byteLength = ds.readUint32() + 8U; + + ds.assumeData({0x00, 0x00, 0x00, 0x00}, getMethodName(this, __func__) + ": 0"); + + locX = ds.readInt32(); + locY = ds.readInt32(); + + spdlog::trace("locX = {}", locX); + spdlog::trace("locY = {}", locY); + + x2 = ds.readInt32(); + y2 = ds.readInt32(); + x1 = ds.readInt32(); + y1 = ds.readInt32(); + + spdlog::trace("x2 = {}", x2); + spdlog::trace("y2 = {}", y2); + spdlog::trace("x1 = {}", x1); + spdlog::trace("y1 = {}", y1); + + // @todo Check if fontIdx with 4 byte fits. I.e. are the following 2 Byte all 0? + textFontIdx = ds.readUint16(); + + spdlog::trace("textFontIdx = {}", textFontIdx); + + if(gLibrary != nullptr) + { + if(gLibrary->library) + { + if(textFontIdx > gLibrary->library->textFonts.size()) + { + throw std::out_of_range(fmt::format("{}: textFontIdx is out of range! Expected {} <= {}!", + getMethodName(this, __func__), textFontIdx, gLibrary->library->textFonts.size())); + } + } + } + + ds.printUnknownData(2, getMethodName(this, __func__) + ": 1"); + + name = ds.readStringLenZeroTerm(); + + spdlog::trace("name = {}", name); + + if(ds.getCurrentOffset() != startOffset + byteLength) + { + // throw MisinterpretedData(__func__, startOffset, byteLength, ds.getCurrentOffset()); + } + + if(byteLength != 39u + name.size()) + { + // throw FileFormatChanged("CommentText"); + } + + readPreamble(); + + spdlog::debug(getClosingMsg(getMethodName(this, __func__), ds.getCurrentOffset())); + spdlog::trace(to_string()); +} + + +LOGFONTA PrimCommentText::getTextFont() const +{ + const int64_t idx = static_cast(textFontIdx) - 1; + + LOGFONTA textFont{}; + + if(idx >= 0) + { + // Retrieve font from the library. + if(gLibrary != nullptr) + { + if(gLibrary->library) + { + textFont = gLibrary->library->textFonts.at(idx); + } + } + // @todo provide try catch block for better exception messages + } + else if(idx == -1) + { + // @todo Unknown but it is probably the default font; + // throw std::runtime_error(getMethodName(this, __func__) + ": Check this out!"); + } + else // idx < -1 + { + // This should never happen. + throw std::runtime_error(getMethodName(this, __func__) + ": Unexpected index " + std::to_string(idx)); + } + + return textFont; } \ No newline at end of file diff --git a/src/Structures/StructSymbolDisplayProp.cpp b/src/Structures/StructSymbolDisplayProp.cpp index 6f4df7d..3f0e41f 100644 --- a/src/Structures/StructSymbolDisplayProp.cpp +++ b/src/Structures/StructSymbolDisplayProp.cpp @@ -29,7 +29,13 @@ void StructSymbolDisplayProp::read(FileFormatVersion /* aVersion */) // @todo move to left shift operator // @bug The required string is not this one but the value of the associated property!!!! // This is just the name of the property!! - spdlog::trace("strLst Item = {}", gLibrary->library->strLst.at(nameIdx)); + if(gLibrary != nullptr) + { + if(gLibrary->library) + { + spdlog::trace("strLst Item = {}", gLibrary->library->strLst.at(nameIdx)); + } + } x = ds.readInt16(); y = ds.readInt16(); @@ -56,13 +62,19 @@ void StructSymbolDisplayProp::read(FileFormatVersion /* aVersion */) // code we had a similar issue. The solution was that the actual vector // index is textFontIdx - 1 and index = 0 is a special case that represents // an empty string i.e. does not need to be loaded from the vector. - if(textFontIdx >= gLibrary->library->textFonts.size()) + if(gLibrary != nullptr) { - const std::string msg = fmt::format("{}: textFontIdx is out of range! Expected {} < {}!", - __func__, textFontIdx, gLibrary->library->textFonts.size()); - - spdlog::warn(msg); - // throw std::out_of_range(msg); + if(gLibrary->library) + { + if(textFontIdx >= gLibrary->library->textFonts.size()) + { + const std::string msg = fmt::format("{}: textFontIdx is out of range! Expected {} < {}!", + __func__, textFontIdx, gLibrary->library->textFonts.size()); + + spdlog::warn(msg); + // throw std::out_of_range(msg); + } + } } rotation = ToRotation(rotFontIdBitField.rotation);