From aea76d0b423f88b137f0399a367170450f3ad71c Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 24 Aug 2023 19:36:37 +0200 Subject: [PATCH] Escape string values when menu dumping --- .../Game/IW4/Menu/MenuDumperIW4.cpp | 2 +- .../Game/IW5/Menu/MenuDumperIW5.cpp | 2 +- src/ObjWriting/Menu/AbstractMenuDumper.cpp | 40 ++++++++++++++++++- src/ObjWriting/Menu/AbstractMenuDumper.h | 2 + 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.cpp b/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.cpp index a24789ef..3007b2a0 100644 --- a/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.cpp @@ -193,7 +193,7 @@ void MenuDumper::WriteStatementOperand(const Statement_s* statement, size_t& cur break; case VAL_STRING: - m_stream << "\"" << operand.internals.stringVal.string << "\""; + WriteEscapedString(operand.internals.stringVal.string); break; case VAL_FUNCTION: diff --git a/src/ObjWriting/Game/IW5/Menu/MenuDumperIW5.cpp b/src/ObjWriting/Game/IW5/Menu/MenuDumperIW5.cpp index 5ca1cce1..fca64e5c 100644 --- a/src/ObjWriting/Game/IW5/Menu/MenuDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/Menu/MenuDumperIW5.cpp @@ -192,7 +192,7 @@ void MenuDumper::WriteStatementOperand(const Statement_s* statement, size_t& cur break; case VAL_STRING: - m_stream << "\"" << operand.internals.stringVal.string << "\""; + WriteEscapedString(operand.internals.stringVal.string); break; case VAL_FUNCTION: diff --git a/src/ObjWriting/Menu/AbstractMenuDumper.cpp b/src/ObjWriting/Menu/AbstractMenuDumper.cpp index 60fef6c9..914926d2 100644 --- a/src/ObjWriting/Menu/AbstractMenuDumper.cpp +++ b/src/ObjWriting/Menu/AbstractMenuDumper.cpp @@ -130,6 +130,38 @@ bool AbstractMenuDumper::DoesTokenNeedQuotationMarks(const std::string& token) return hasNonIdentifierCharacter; } +void AbstractMenuDumper::WriteEscapedString(const std::string_view& str) const +{ + m_stream << "\""; + + for (const auto& c : str) + { + switch (c) + { + case '\r': + m_stream << "\\r"; + break; + case '\n': + m_stream << "\\n"; + break; + case '\t': + m_stream << "\\t"; + break; + case '\f': + m_stream << "\\f"; + break; + case '"': + m_stream << "\\\""; + break; + default: + m_stream << c; + break; + } + } + + m_stream << "\""; +} + const std::string& AbstractMenuDumper::BoolValue(const bool value) { return value ? BOOL_VALUE_TRUE : BOOL_VALUE_FALSE; @@ -154,7 +186,9 @@ void AbstractMenuDumper::WriteStringProperty(const std::string& propertyKey, con Indent(); WriteKey(propertyKey); - m_stream << "\"" << propertyValue << "\"\n"; + + WriteEscapedString(propertyValue); + m_stream << "\n"; } void AbstractMenuDumper::WriteStringProperty(const std::string& propertyKey, const char* propertyValue) const @@ -164,7 +198,9 @@ void AbstractMenuDumper::WriteStringProperty(const std::string& propertyKey, con Indent(); WriteKey(propertyKey); - m_stream << "\"" << propertyValue << "\"\n"; + + WriteEscapedString(propertyValue); + m_stream << "\n"; } void AbstractMenuDumper::WriteBoolProperty(const std::string& propertyKey, const bool propertyValue, const bool defaultValue) const diff --git a/src/ObjWriting/Menu/AbstractMenuDumper.h b/src/ObjWriting/Menu/AbstractMenuDumper.h index 669586e6..5a826d05 100644 --- a/src/ObjWriting/Menu/AbstractMenuDumper.h +++ b/src/ObjWriting/Menu/AbstractMenuDumper.h @@ -30,6 +30,8 @@ protected: static std::vector CreateScriptTokenList(const char* script); static bool DoesTokenNeedQuotationMarks(const std::string& token); + void WriteEscapedString(const std::string_view& str) const; + static const std::string& BoolValue(bool value); void WriteKey(const std::string& keyName) const; void WriteStringProperty(const std::string& propertyKey, const std::string& propertyValue) const;