diff options
author | Szymon Kłos <szymon.klos@collabora.com> | 2021-12-08 11:53:35 +0100 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2021-12-09 13:26:51 +0100 |
commit | 399d0559cbb721c1e0ca6b302e11889ddee97f90 (patch) | |
tree | 69fbbfd246a6547c44e460ce70b2f11791e0b450 | |
parent | make sure vector elements are initialized properly (diff) | |
download | core-399d0559cbb721c1e0ca6b302e11889ddee97f90.tar.gz core-399d0559cbb721c1e0ca6b302e11889ddee97f90.zip |
jsonwriter: ensure correct number of bytes is available
In some functions author forgot that addCommaBeforeField()
can add additional two characters.
I didn't change cases where more bytes than needed are requested.
Additional change is that in debug mode there is a marker at the
end of allocated buffer - we check that after every write to
detect overflow. No need to request more space for a marker as
we always allocate "needed size * 2".
Change-Id: I28066797b0ba833e408b0a731abc01b7fd989da3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126535
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
-rw-r--r-- | include/tools/json_writer.hxx | 20 | ||||
-rw-r--r-- | tools/source/misc/json_writer.cxx | 41 |
2 files changed, 59 insertions, 2 deletions
diff --git a/include/tools/json_writer.hxx b/include/tools/json_writer.hxx index 2e50670c5b26..318faef70fee 100644 --- a/include/tools/json_writer.hxx +++ b/include/tools/json_writer.hxx @@ -91,9 +91,29 @@ private: { assert(mpBuffer && "already extracted data"); int currentUsed = mPos - mpBuffer; + +#ifndef NDEBUG + currentUsed++; // validation marker +#endif + if (currentUsed + noMoreBytesRequired >= mSpaceAllocated) reallocBuffer(noMoreBytesRequired); } + + // overflow validation in debug mode + static constexpr char JSON_WRITER_DEBUG_MARKER = 0xde; + + inline void addValidationMark() + { +#ifndef NDEBUG + *(mpBuffer + mSpaceAllocated - 1) = JSON_WRITER_DEBUG_MARKER; +#endif + } + + inline void validate() + { + assert(*(mpBuffer + mSpaceAllocated - 1) == JSON_WRITER_DEBUG_MARKER); + } }; /** diff --git a/tools/source/misc/json_writer.cxx b/tools/source/misc/json_writer.cxx index 0bcbbddc606d..0072e57f1eb6 100644 --- a/tools/source/misc/json_writer.cxx +++ b/tools/source/misc/json_writer.cxx @@ -31,6 +31,8 @@ JsonWriter::JsonWriter() ++mPos; *mPos = ' '; ++mPos; + + addValidationMark(); } JsonWriter::~JsonWriter() @@ -42,7 +44,7 @@ JsonWriter::~JsonWriter() ScopedJsonWriterNode JsonWriter::startNode(const char* pNodeName) { auto len = strlen(pNodeName); - ensureSpace(len + 6); + ensureSpace(len + 8); addCommaBeforeField(); @@ -54,6 +56,9 @@ ScopedJsonWriterNode JsonWriter::startNode(const char* pNodeName) mPos += 5; mStartNodeCount++; mbFirstFieldInNode = true; + + validate(); + return ScopedJsonWriterNode(*this); } @@ -65,12 +70,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(); @@ -82,6 +89,9 @@ ScopedJsonWriterArray JsonWriter::startArray(const char* pNodeName) mPos += 5; mStartNodeCount++; mbFirstFieldInNode = true; + + validate(); + return ScopedJsonWriterArray(*this); } @@ -93,6 +103,8 @@ void JsonWriter::endArray() *mPos = ']'; ++mPos; mbFirstFieldInNode = false; + + validate(); } ScopedJsonWriterStruct JsonWriter::startStruct() @@ -107,6 +119,9 @@ ScopedJsonWriterStruct JsonWriter::startStruct() ++mPos; mStartNodeCount++; mbFirstFieldInNode = true; + + validate(); + return ScopedJsonWriterStruct(*this); } @@ -118,6 +133,8 @@ void JsonWriter::endStruct() *mPos = '}'; ++mPos; mbFirstFieldInNode = false; + + validate(); } void JsonWriter::writeEscapedOUString(const OUString& rPropVal) @@ -195,6 +212,8 @@ void JsonWriter::writeEscapedOUString(const OUString& rPropVal) ++mPos; } } + + validate(); } void JsonWriter::put(const char* pPropName, const OUString& rPropVal) @@ -219,6 +238,8 @@ void JsonWriter::put(const char* pPropName, const OUString& rPropVal) *mPos = '"'; ++mPos; + + validate(); } void JsonWriter::put(const char* pPropName, const OString& rPropVal) @@ -265,6 +286,8 @@ void JsonWriter::put(const char* pPropName, const OString& rPropVal) *mPos = '"'; ++mPos; + + validate(); } void JsonWriter::put(const char* pPropName, const char* pPropVal) @@ -313,6 +336,8 @@ void JsonWriter::put(const char* pPropName, const char* pPropVal) *mPos = '"'; ++mPos; + + validate(); } void JsonWriter::put(const char* pPropName, sal_Int64 nPropVal) @@ -331,6 +356,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) @@ -350,6 +377,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) @@ -373,6 +402,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) @@ -389,6 +420,8 @@ void JsonWriter::putSimpleValue(const OUString& rPropVal) *mPos = '"'; ++mPos; + + validate(); } void JsonWriter::putRaw(const rtl::OStringBuffer& rRawBuf) @@ -399,6 +432,8 @@ void JsonWriter::putRaw(const rtl::OStringBuffer& rRawBuf) memcpy(mPos, rRawBuf.getStr(), rRawBuf.getLength()); mPos += rRawBuf.getLength(); + + validate(); } void JsonWriter::addCommaBeforeField() @@ -424,6 +459,8 @@ void JsonWriter::reallocBuffer(int noMoreBytesRequired) mpBuffer = pNew; mPos = mpBuffer + currentUsed; mSpaceAllocated = newSize; + + addValidationMark(); } /** Hands ownership of the underlying storage buffer to the caller, |