Fix crash when trying to read/write a string with 0 length

This commit is contained in:
Phillip Stephens 2015-12-05 19:37:26 -08:00
parent 259d2de59a
commit 028e4323e1
2 changed files with 92 additions and 54 deletions

View File

@ -883,6 +883,9 @@ public:
*/ */
inline std::string readWStringAsString(atInt32 fixedLen = -1) inline std::string readWStringAsString(atInt32 fixedLen = -1)
{ {
if (fixedLen == 0)
return std::string();
std::string retval; std::string retval;
atUint16 chr = readUint16(); atUint16 chr = readUint16();
@ -921,6 +924,9 @@ public:
*/ */
inline std::string readWStringAsStringLittle(atInt32 fixedLen = -1) inline std::string readWStringAsStringLittle(atInt32 fixedLen = -1)
{ {
if (fixedLen == 0)
return std::string();
std::string retval; std::string retval;
atUint16 chr = readUint16Little(); atUint16 chr = readUint16Little();
@ -959,6 +965,9 @@ public:
*/ */
inline std::string readWStringAsStringBig(atInt32 fixedLen = -1) inline std::string readWStringAsStringBig(atInt32 fixedLen = -1)
{ {
if (fixedLen == 0)
return std::string();
std::string retval; std::string retval;
atUint16 chr = readUint16Big(); atUint16 chr = readUint16Big();
@ -996,6 +1005,8 @@ public:
*/ */
inline std::string readString(atInt32 fixedLen = -1) inline std::string readString(atInt32 fixedLen = -1)
{ {
if (fixedLen == 0)
return std::string();
std::string ret; std::string ret;
atUint8 chr = readByte(); atUint8 chr = readByte();
@ -1026,6 +1037,9 @@ public:
*/ */
inline std::wstring readWString(atInt32 fixedLen = -1) inline std::wstring readWString(atInt32 fixedLen = -1)
{ {
if (fixedLen == 0)
return std::wstring();
std::wstring ret; std::wstring ret;
atUint16 chr = readUint16(); atUint16 chr = readUint16();
@ -1057,6 +1071,9 @@ public:
*/ */
inline std::wstring readWStringLittle(atInt32 fixedLen = -1) inline std::wstring readWStringLittle(atInt32 fixedLen = -1)
{ {
if (fixedLen == 0)
return std::wstring();
std::wstring ret; std::wstring ret;
atUint16 chr = readUint16Little(); atUint16 chr = readUint16Little();
@ -1088,6 +1105,8 @@ public:
*/ */
inline std::wstring readWStringBig(atInt32 fixedLen = -1) inline std::wstring readWStringBig(atInt32 fixedLen = -1)
{ {
if (fixedLen == 0)
return std::wstring();
std::wstring ret; std::wstring ret;
atUint16 chr = readUint16Big(); atUint16 chr = readUint16Big();

View File

@ -712,50 +712,52 @@ public:
*/ */
inline void writeStringAsWString(const std::string& str, atInt32 fixedLen = -1) inline void writeStringAsWString(const std::string& str, atInt32 fixedLen = -1)
{ {
std::string tmpStr = "\xEF\xBB\xBF" + str; if (fixedLen == 0)
const utf8proc_uint8_t* buf = reinterpret_cast<const utf8proc_uint8_t*>(tmpStr.c_str()); return;
if (fixedLen < 0) std::string tmpStr = "\xEF\xBB\xBF" + str;
{ const utf8proc_uint8_t* buf = reinterpret_cast<const utf8proc_uint8_t*>(tmpStr.c_str());
while (*buf) if (fixedLen < 0)
{ {
utf8proc_int32_t wc; while (*buf)
utf8proc_ssize_t len = utf8proc_iterate(buf, -1, &wc); {
if (len < 0) utf8proc_int32_t wc;
{ utf8proc_ssize_t len = utf8proc_iterate(buf, -1, &wc);
atWarning("invalid UTF-8 character while decoding"); if (len < 0)
return; {
} atWarning("invalid UTF-8 character while decoding");
buf += len; return;
if (wc != 0xFEFF) }
writeUint16(atUint16(wc)); buf += len;
} if (wc != 0xFEFF)
writeUint16(0); writeUint16(atUint16(wc));
} }
else writeUint16(0);
{ }
for (atInt32 i=0 ; i<fixedLen ; ++i) else
{ {
utf8proc_int32_t wc = 0; for (atInt32 i=0 ; i<fixedLen ; ++i)
if (*buf) {
{ utf8proc_int32_t wc = 0;
utf8proc_ssize_t len = utf8proc_iterate(buf, -1, &wc); if (*buf)
if (len < 0) {
{ utf8proc_ssize_t len = utf8proc_iterate(buf, -1, &wc);
atWarning("invalid UTF-8 character while decoding"); if (len < 0)
return; {
} atWarning("invalid UTF-8 character while decoding");
buf += len; return;
} }
buf += len;
}
if (wc == 0xFEFF) if (wc == 0xFEFF)
{ {
--i; --i;
continue; continue;
} }
writeUint16(atUint16(wc)); writeUint16(atUint16(wc));
} }
} }
} }
/** @brief Converts a UTF8 string to a wide-char string in the buffer and advances the buffer. /** @brief Converts a UTF8 string to a wide-char string in the buffer and advances the buffer.
@ -768,6 +770,8 @@ public:
*/ */
inline void writeStringAsWStringLittle(const std::string& str, atInt32 fixedLen = -1) inline void writeStringAsWStringLittle(const std::string& str, atInt32 fixedLen = -1)
{ {
if (fixedLen == 0)
return;
std::string tmpStr = "\xEF\xBB\xBF" + str; std::string tmpStr = "\xEF\xBB\xBF" + str;
const utf8proc_uint8_t* buf = reinterpret_cast<const utf8proc_uint8_t*>(tmpStr.c_str()); const utf8proc_uint8_t* buf = reinterpret_cast<const utf8proc_uint8_t*>(tmpStr.c_str());
if (fixedLen < 0) if (fixedLen < 0)
@ -824,6 +828,9 @@ public:
*/ */
inline void writeStringAsWStringBig(const std::string& str, atInt32 fixedLen = -1) inline void writeStringAsWStringBig(const std::string& str, atInt32 fixedLen = -1)
{ {
if (fixedLen == 0)
return;
std::string tmpStr = "\xEF\xBB\xBF" + str; std::string tmpStr = "\xEF\xBB\xBF" + str;
const utf8proc_uint8_t* buf = reinterpret_cast<const utf8proc_uint8_t*>(tmpStr.c_str()); const utf8proc_uint8_t* buf = reinterpret_cast<const utf8proc_uint8_t*>(tmpStr.c_str());
if (fixedLen < 0) if (fixedLen < 0)
@ -877,6 +884,9 @@ public:
*/ */
inline void writeString(const std::string& str, atInt32 fixedLen = -1) inline void writeString(const std::string& str, atInt32 fixedLen = -1)
{ {
if (fixedLen == 0)
return;
if (fixedLen < 0) if (fixedLen < 0)
{ {
for (atUint8 c : str) for (atUint8 c : str)
@ -913,6 +923,9 @@ public:
*/ */
inline void writeWString(const std::wstring& str, atInt32 fixedLen = -1) inline void writeWString(const std::wstring& str, atInt32 fixedLen = -1)
{ {
if (fixedLen == 0)
return;
if (fixedLen < 0) if (fixedLen < 0)
{ {
for (atUint16 c : str) for (atUint16 c : str)
@ -949,6 +962,9 @@ public:
*/ */
inline void writeWStringLittle(const std::wstring& str, atInt32 fixedLen = -1) inline void writeWStringLittle(const std::wstring& str, atInt32 fixedLen = -1)
{ {
if (fixedLen == 0)
return;
if (fixedLen < 0) if (fixedLen < 0)
{ {
for (atUint16 c : str) for (atUint16 c : str)
@ -985,6 +1001,9 @@ public:
*/ */
inline void writeWStringBig(const std::wstring& str, atInt32 fixedLen = -1) inline void writeWStringBig(const std::wstring& str, atInt32 fixedLen = -1)
{ {
if (fixedLen == 0)
return;
if (fixedLen < 0) if (fixedLen < 0)
{ {
for (atUint16 c : str) for (atUint16 c : str)
@ -1025,9 +1044,9 @@ public:
template <class T> template <class T>
void enumerate(const std::vector<T>& vector, void enumerate(const std::vector<T>& vector,
typename std::enable_if<std::is_arithmetic<T>::value || typename std::enable_if<std::is_arithmetic<T>::value ||
std::is_same<T, atVec2f>::value || std::is_same<T, atVec2f>::value ||
std::is_same<T, atVec3f>::value || std::is_same<T, atVec3f>::value ||
std::is_same<T, atVec4f>::value>::type* = 0) std::is_same<T, atVec4f>::value>::type* = 0)
{ {
for (const T& item : vector) for (const T& item : vector)
writeVal(item); writeVal(item);
@ -1041,9 +1060,9 @@ public:
template <class T> template <class T>
void enumerateLittle(const std::vector<T>& vector, void enumerateLittle(const std::vector<T>& vector,
typename std::enable_if<std::is_arithmetic<T>::value || typename std::enable_if<std::is_arithmetic<T>::value ||
std::is_same<T, atVec2f>::value || std::is_same<T, atVec2f>::value ||
std::is_same<T, atVec3f>::value || std::is_same<T, atVec3f>::value ||
std::is_same<T, atVec4f>::value>::type* = 0) std::is_same<T, atVec4f>::value>::type* = 0)
{ {
for (const T& item : vector) for (const T& item : vector)
writeValLittle(item); writeValLittle(item);
@ -1057,9 +1076,9 @@ public:
template <class T> template <class T>
void enumerateBig(const std::vector<T>& vector, void enumerateBig(const std::vector<T>& vector,
typename std::enable_if<std::is_arithmetic<T>::value || typename std::enable_if<std::is_arithmetic<T>::value ||
std::is_same<T, atVec2f>::value || std::is_same<T, atVec2f>::value ||
std::is_same<T, atVec3f>::value || std::is_same<T, atVec3f>::value ||
std::is_same<T, atVec4f>::value>::type* = 0) std::is_same<T, atVec4f>::value>::type* = 0)
{ {
for (const T& item : vector) for (const T& item : vector)
writeValBig(item); writeValBig(item);
@ -1071,9 +1090,9 @@ public:
template <class T> template <class T>
void enumerate(const std::vector<T>& vector, void enumerate(const std::vector<T>& vector,
typename std::enable_if<!std::is_arithmetic<T>::value && typename std::enable_if<!std::is_arithmetic<T>::value &&
!std::is_same<T, atVec2f>::value && !std::is_same<T, atVec2f>::value &&
!std::is_same<T, atVec3f>::value && !std::is_same<T, atVec3f>::value &&
!std::is_same<T, atVec4f>::value>::type* = 0) !std::is_same<T, atVec4f>::value>::type* = 0)
{ {
for (const T& item : vector) for (const T& item : vector)
item.write(*this); item.write(*this);