From c510683d2a64e75a667134ef0b63e9638c474c28 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 2 Jan 2014 17:33:18 +0100 Subject: [PATCH] Fixed unaligned memory access in FastNBT. This should fix #420. --- src/StringUtils.cpp | 30 ++++++++++++++++++++++++++++++ src/StringUtils.h | 9 +++++++++ src/WorldStorage/FastNBT.cpp | 10 +++++----- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index f7aeeed26..5c6b99d88 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -764,3 +764,33 @@ AString Base64Decode(const AString & a_Base64String) + +short GetBEShort(const char * a_Mem) +{ + return (((short)a_Mem[0]) << 8) | a_Mem[1]; +} + + + + + +int GetBEInt(const char * a_Mem) +{ + return (((int)a_Mem[0]) << 24) | (((int)a_Mem[1]) << 16) | (((int)a_Mem[2]) << 8) | a_Mem[3]; +} + + + + + +void SetBEInt(char * a_Mem, Int32 a_Value) +{ + a_Mem[0] = a_Value >> 24; + a_Mem[1] = (a_Value >> 16) & 0xff; + a_Mem[2] = (a_Value >> 8) & 0xff; + a_Mem[3] = a_Value & 0xff; +} + + + + diff --git a/src/StringUtils.h b/src/StringUtils.h index 3917cc4ec..471e843e4 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -81,6 +81,15 @@ extern AString ReplaceAllCharOccurrences(const AString & a_String, char a_From, /// Decodes a Base64-encoded string into the raw data extern AString Base64Decode(const AString & a_Base64String); +/// Reads two bytes from the specified memory location and interprets them as BigEndian short +extern short GetBEShort(const char * a_Mem); + +/// Reads four bytes from the specified memory location and interprets them as BigEndian int +extern int GetBEInt(const char * a_Mem); + +/// Writes four bytes to the specified memory location so that they interpret as BigEndian int +extern void SetBEInt(char * a_Mem, Int32 a_Value); + // If you have any other string helper functions, declare them here diff --git a/src/WorldStorage/FastNBT.cpp b/src/WorldStorage/FastNBT.cpp index e55011069..64220f09a 100644 --- a/src/WorldStorage/FastNBT.cpp +++ b/src/WorldStorage/FastNBT.cpp @@ -80,7 +80,7 @@ bool cParsedNBT::ReadString(int & a_StringStart, int & a_StringLen) { NEEDBYTES(2); a_StringStart = m_Pos + 2; - a_StringLen = ntohs(*((short *)(m_Data + m_Pos))); + a_StringLen = GetBEShort(m_Data + m_Pos); if (a_StringLen < 0) { // Invalid string length @@ -135,7 +135,7 @@ bool cParsedNBT::ReadList(eTagType a_ChildrenType) // Read the count: NEEDBYTES(4); - int Count = ntohl(*((int *)(m_Data + m_Pos))); + int Count = GetBEInt(m_Data + m_Pos); m_Pos += 4; if (Count < 0) { @@ -197,7 +197,7 @@ bool cParsedNBT::ReadTag(void) case TAG_ByteArray: { NEEDBYTES(4); - int len = ntohl(*((int *)(m_Data + m_Pos))); + int len = GetBEInt(m_Data + m_Pos); m_Pos += 4; if (len < 0) { @@ -229,7 +229,7 @@ bool cParsedNBT::ReadTag(void) case TAG_IntArray: { NEEDBYTES(4); - int len = ntohl(*((int *)(m_Data + m_Pos))); + int len = GetBEInt(m_Data + m_Pos); m_Pos += 4; if (len < 0) { @@ -401,7 +401,7 @@ void cFastNBTWriter::EndList(void) ASSERT(m_Stack[m_CurrentStack].m_Type == TAG_List); // Update the list count: - *((int *)(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos)) = htonl(m_Stack[m_CurrentStack].m_Count); + SetBEInt((char *)(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos), m_Stack[m_CurrentStack].m_Count); --m_CurrentStack; }