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-on: https://gerrit.libreoffice.org/c/core/+/129163 Tested-by: Jenkins Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
This commit is contained in:
committed by
Michael Meeks
parent
9b5894e67d
commit
496fcccfa6
@@ -89,6 +89,24 @@ private:
|
||||
void writeEscapedOUString(const OUString& rPropVal);
|
||||
std::pair<char*, int> 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
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -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<char*>(realloc(mpBuffer, newSize));
|
||||
mPos = mpBuffer + currentUsed;
|
||||
mSpaceAllocated = newSize;
|
||||
|
||||
addValidationMark();
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user