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);
|
void writeEscapedOUString(const OUString& rPropVal);
|
||||||
std::pair<char*, int> extractDataImpl();
|
std::pair<char*, int> extractDataImpl();
|
||||||
void ensureSpace(int noMoreBytesRequired);
|
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 = ' ';
|
*mPos = ' ';
|
||||||
++mPos;
|
++mPos;
|
||||||
|
|
||||||
|
addValidationMark();
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonWriter::~JsonWriter()
|
JsonWriter::~JsonWriter()
|
||||||
@@ -41,7 +43,7 @@ JsonWriter::~JsonWriter()
|
|||||||
ScopedJsonWriterNode JsonWriter::startNode(const char* pNodeName)
|
ScopedJsonWriterNode JsonWriter::startNode(const char* pNodeName)
|
||||||
{
|
{
|
||||||
auto len = strlen(pNodeName);
|
auto len = strlen(pNodeName);
|
||||||
ensureSpace(len + 6);
|
ensureSpace(len + 8);
|
||||||
|
|
||||||
addCommaBeforeField();
|
addCommaBeforeField();
|
||||||
|
|
||||||
@@ -53,6 +55,9 @@ ScopedJsonWriterNode JsonWriter::startNode(const char* pNodeName)
|
|||||||
mPos += 5;
|
mPos += 5;
|
||||||
mStartNodeCount++;
|
mStartNodeCount++;
|
||||||
mbFirstFieldInNode = true;
|
mbFirstFieldInNode = true;
|
||||||
|
|
||||||
|
validate();
|
||||||
|
|
||||||
return ScopedJsonWriterNode(*this);
|
return ScopedJsonWriterNode(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,12 +69,14 @@ void JsonWriter::endNode()
|
|||||||
*mPos = '}';
|
*mPos = '}';
|
||||||
++mPos;
|
++mPos;
|
||||||
mbFirstFieldInNode = false;
|
mbFirstFieldInNode = false;
|
||||||
|
|
||||||
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopedJsonWriterArray JsonWriter::startArray(const char* pNodeName)
|
ScopedJsonWriterArray JsonWriter::startArray(const char* pNodeName)
|
||||||
{
|
{
|
||||||
auto len = strlen(pNodeName);
|
auto len = strlen(pNodeName);
|
||||||
ensureSpace(len + 6);
|
ensureSpace(len + 8);
|
||||||
|
|
||||||
addCommaBeforeField();
|
addCommaBeforeField();
|
||||||
|
|
||||||
@@ -81,6 +88,9 @@ ScopedJsonWriterArray JsonWriter::startArray(const char* pNodeName)
|
|||||||
mPos += 5;
|
mPos += 5;
|
||||||
mStartNodeCount++;
|
mStartNodeCount++;
|
||||||
mbFirstFieldInNode = true;
|
mbFirstFieldInNode = true;
|
||||||
|
|
||||||
|
validate();
|
||||||
|
|
||||||
return ScopedJsonWriterArray(*this);
|
return ScopedJsonWriterArray(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +102,8 @@ void JsonWriter::endArray()
|
|||||||
*mPos = ']';
|
*mPos = ']';
|
||||||
++mPos;
|
++mPos;
|
||||||
mbFirstFieldInNode = false;
|
mbFirstFieldInNode = false;
|
||||||
|
|
||||||
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopedJsonWriterStruct JsonWriter::startStruct()
|
ScopedJsonWriterStruct JsonWriter::startStruct()
|
||||||
@@ -106,6 +118,9 @@ ScopedJsonWriterStruct JsonWriter::startStruct()
|
|||||||
++mPos;
|
++mPos;
|
||||||
mStartNodeCount++;
|
mStartNodeCount++;
|
||||||
mbFirstFieldInNode = true;
|
mbFirstFieldInNode = true;
|
||||||
|
|
||||||
|
validate();
|
||||||
|
|
||||||
return ScopedJsonWriterStruct(*this);
|
return ScopedJsonWriterStruct(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,6 +132,8 @@ void JsonWriter::endStruct()
|
|||||||
*mPos = '}';
|
*mPos = '}';
|
||||||
++mPos;
|
++mPos;
|
||||||
mbFirstFieldInNode = false;
|
mbFirstFieldInNode = false;
|
||||||
|
|
||||||
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
static char getEscapementChar(char ch)
|
static char getEscapementChar(char ch)
|
||||||
@@ -211,6 +228,8 @@ void JsonWriter::writeEscapedOUString(const OUString& rPropVal)
|
|||||||
++mPos;
|
++mPos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonWriter::put(const char* pPropName, const OUString& rPropVal)
|
void JsonWriter::put(const char* pPropName, const OUString& rPropVal)
|
||||||
@@ -234,6 +253,8 @@ void JsonWriter::put(const char* pPropName, const OUString& rPropVal)
|
|||||||
|
|
||||||
*mPos = '"';
|
*mPos = '"';
|
||||||
++mPos;
|
++mPos;
|
||||||
|
|
||||||
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonWriter::put(const char* pPropName, std::string_view rPropVal)
|
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 = '"';
|
||||||
++mPos;
|
++mPos;
|
||||||
|
|
||||||
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonWriter::put(const char* pPropName, sal_Int64 nPropVal)
|
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 += 3;
|
||||||
|
|
||||||
mPos += sprintf(mPos, "%" SAL_PRIdINT64, nPropVal);
|
mPos += sprintf(mPos, "%" SAL_PRIdINT64, nPropVal);
|
||||||
|
|
||||||
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonWriter::put(const char* pPropName, double fPropVal)
|
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());
|
memcpy(mPos, sPropVal.getStr(), sPropVal.getLength());
|
||||||
mPos += sPropVal.getLength();
|
mPos += sPropVal.getLength();
|
||||||
|
|
||||||
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonWriter::put(const char* pPropName, bool nPropVal)
|
void JsonWriter::put(const char* pPropName, bool nPropVal)
|
||||||
@@ -347,6 +374,8 @@ void JsonWriter::put(const char* pPropName, bool nPropVal)
|
|||||||
pVal = "false";
|
pVal = "false";
|
||||||
memcpy(mPos, pVal, strlen(pVal));
|
memcpy(mPos, pVal, strlen(pVal));
|
||||||
mPos += strlen(pVal);
|
mPos += strlen(pVal);
|
||||||
|
|
||||||
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonWriter::putSimpleValue(const OUString& rPropVal)
|
void JsonWriter::putSimpleValue(const OUString& rPropVal)
|
||||||
@@ -363,6 +392,8 @@ void JsonWriter::putSimpleValue(const OUString& rPropVal)
|
|||||||
|
|
||||||
*mPos = '"';
|
*mPos = '"';
|
||||||
++mPos;
|
++mPos;
|
||||||
|
|
||||||
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonWriter::putRaw(std::string_view rRawBuf)
|
void JsonWriter::putRaw(std::string_view rRawBuf)
|
||||||
@@ -373,6 +404,8 @@ void JsonWriter::putRaw(std::string_view rRawBuf)
|
|||||||
|
|
||||||
memcpy(mPos, rRawBuf.data(), rRawBuf.size());
|
memcpy(mPos, rRawBuf.data(), rRawBuf.size());
|
||||||
mPos += rRawBuf.size();
|
mPos += rRawBuf.size();
|
||||||
|
|
||||||
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonWriter::addCommaBeforeField()
|
void JsonWriter::addCommaBeforeField()
|
||||||
@@ -398,6 +431,8 @@ void JsonWriter::ensureSpace(int noMoreBytesRequired)
|
|||||||
mpBuffer = static_cast<char*>(realloc(mpBuffer, newSize));
|
mpBuffer = static_cast<char*>(realloc(mpBuffer, newSize));
|
||||||
mPos = mpBuffer + currentUsed;
|
mPos = mpBuffer + currentUsed;
|
||||||
mSpaceAllocated = newSize;
|
mSpaceAllocated = newSize;
|
||||||
|
|
||||||
|
addValidationMark();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user