summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSzymon Kłos <szymon.klos@collabora.com>2021-12-08 11:53:35 +0100
committerAndras Timar <andras.timar@collabora.com>2021-12-09 13:26:51 +0100
commit399d0559cbb721c1e0ca6b302e11889ddee97f90 (patch)
tree69fbbfd246a6547c44e460ce70b2f11791e0b450
parentmake sure vector elements are initialized properly (diff)
downloadcore-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.hxx20
-rw-r--r--tools/source/misc/json_writer.cxx41
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,