diff --git a/include/tools/json_writer.hxx b/include/tools/json_writer.hxx index 72ed59edadc5..700e82b9a2c6 100644 --- a/include/tools/json_writer.hxx +++ b/include/tools/json_writer.hxx @@ -89,6 +89,24 @@ private: void writeEscapedOUString(const OUString& rPropVal); std::pair extractDataImpl(); void ensureSpace(int noMoreBytesRequired); + + // overflow validation in debug mode + static constexpr unsigned char JSON_WRITER_DEBUG_MARKER = 0xde; + + inline void addValidationMark() + { +#ifndef NDEBUG + *(mpBuffer + mSpaceAllocated - 1) = JSON_WRITER_DEBUG_MARKER; +#endif + } + + inline void validate() + { +#ifndef NDEBUG + unsigned char c = *(mpBuffer + mSpaceAllocated - 1); + assert(c == JSON_WRITER_DEBUG_MARKER); +#endif + } }; /** diff --git a/tools/source/misc/json_writer.cxx b/tools/source/misc/json_writer.cxx index d6e34179f930..7730a9a603d5 100644 --- a/tools/source/misc/json_writer.cxx +++ b/tools/source/misc/json_writer.cxx @@ -30,6 +30,8 @@ JsonWriter::JsonWriter() ++mPos; *mPos = ' '; ++mPos; + + addValidationMark(); } JsonWriter::~JsonWriter() @@ -41,7 +43,7 @@ JsonWriter::~JsonWriter() ScopedJsonWriterNode JsonWriter::startNode(const char* pNodeName) { auto len = strlen(pNodeName); - ensureSpace(len + 6); + ensureSpace(len + 8); addCommaBeforeField(); @@ -53,6 +55,9 @@ ScopedJsonWriterNode JsonWriter::startNode(const char* pNodeName) mPos += 5; mStartNodeCount++; mbFirstFieldInNode = true; + + validate(); + return ScopedJsonWriterNode(*this); } @@ -64,12 +69,14 @@ void JsonWriter::endNode() *mPos = '}'; ++mPos; mbFirstFieldInNode = false; + + validate(); } ScopedJsonWriterArray JsonWriter::startArray(const char* pNodeName) { auto len = strlen(pNodeName); - ensureSpace(len + 6); + ensureSpace(len + 8); addCommaBeforeField(); @@ -81,6 +88,9 @@ ScopedJsonWriterArray JsonWriter::startArray(const char* pNodeName) mPos += 5; mStartNodeCount++; mbFirstFieldInNode = true; + + validate(); + return ScopedJsonWriterArray(*this); } @@ -92,6 +102,8 @@ void JsonWriter::endArray() *mPos = ']'; ++mPos; mbFirstFieldInNode = false; + + validate(); } ScopedJsonWriterStruct JsonWriter::startStruct() @@ -106,6 +118,9 @@ ScopedJsonWriterStruct JsonWriter::startStruct() ++mPos; mStartNodeCount++; mbFirstFieldInNode = true; + + validate(); + return ScopedJsonWriterStruct(*this); } @@ -117,6 +132,8 @@ void JsonWriter::endStruct() *mPos = '}'; ++mPos; mbFirstFieldInNode = false; + + validate(); } static char getEscapementChar(char ch) @@ -211,6 +228,8 @@ void JsonWriter::writeEscapedOUString(const OUString& rPropVal) ++mPos; } } + + validate(); } void JsonWriter::put(const char* pPropName, const OUString& rPropVal) @@ -234,6 +253,8 @@ void JsonWriter::put(const char* pPropName, const OUString& rPropVal) *mPos = '"'; ++mPos; + + validate(); } void JsonWriter::put(const char* pPropName, std::string_view rPropVal) @@ -287,6 +308,8 @@ void JsonWriter::put(const char* pPropName, std::string_view rPropVal) *mPos = '"'; ++mPos; + + validate(); } void JsonWriter::put(const char* pPropName, sal_Int64 nPropVal) @@ -305,6 +328,8 @@ void JsonWriter::put(const char* pPropName, sal_Int64 nPropVal) mPos += 3; mPos += sprintf(mPos, "%" SAL_PRIdINT64, nPropVal); + + validate(); } void JsonWriter::put(const char* pPropName, double fPropVal) @@ -324,6 +349,8 @@ void JsonWriter::put(const char* pPropName, double fPropVal) memcpy(mPos, sPropVal.getStr(), sPropVal.getLength()); mPos += sPropVal.getLength(); + + validate(); } void JsonWriter::put(const char* pPropName, bool nPropVal) @@ -347,6 +374,8 @@ void JsonWriter::put(const char* pPropName, bool nPropVal) pVal = "false"; memcpy(mPos, pVal, strlen(pVal)); mPos += strlen(pVal); + + validate(); } void JsonWriter::putSimpleValue(const OUString& rPropVal) @@ -363,6 +392,8 @@ void JsonWriter::putSimpleValue(const OUString& rPropVal) *mPos = '"'; ++mPos; + + validate(); } void JsonWriter::putRaw(std::string_view rRawBuf) @@ -373,6 +404,8 @@ void JsonWriter::putRaw(std::string_view rRawBuf) memcpy(mPos, rRawBuf.data(), rRawBuf.size()); mPos += rRawBuf.size(); + + validate(); } void JsonWriter::addCommaBeforeField() @@ -398,6 +431,8 @@ void JsonWriter::ensureSpace(int noMoreBytesRequired) mpBuffer = static_cast(realloc(mpBuffer, newSize)); mPos = mpBuffer + currentUsed; mSpaceAllocated = newSize; + + addValidationMark(); } }