forked from 0ad/0ad
Avoid misaligned pointer dereferences, which can fail on ARM.
Based on patch by BogDan. Refs #2996. This was SVN commit r16205.
This commit is contained in:
parent
c9c80a9d94
commit
8a39ea5543
@ -28,7 +28,13 @@ const char* UnfinishedHeaderMagicStr = "XMBu";
|
||||
// need to invalidate old users' caches
|
||||
const u32 XMBVersion = 3;
|
||||
|
||||
// Warning: May contain traces of pointer abuse
|
||||
template<typename T>
|
||||
static inline T read(const void* ptr)
|
||||
{
|
||||
T ret;
|
||||
memcpy(&ret, ptr, sizeof(T));
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool XMBFile::Initialise(const char* FileData)
|
||||
{
|
||||
@ -41,7 +47,7 @@ bool XMBFile::Initialise(const char* FileData)
|
||||
return false;
|
||||
ENSURE(!strcmp(Header, HeaderMagicStr) && "Invalid XMB header!");
|
||||
|
||||
u32 Version = *(u32*)m_Pointer;
|
||||
u32 Version = read<u32>(m_Pointer);
|
||||
m_Pointer += 4;
|
||||
if (Version != XMBVersion)
|
||||
return false;
|
||||
@ -55,25 +61,25 @@ bool XMBFile::Initialise(const char* FileData)
|
||||
|
||||
#ifdef XERO_USEMAP
|
||||
// Build a std::map of all the names->ids
|
||||
u32 ElementNameCount = *(u32*)m_Pointer; m_Pointer += 4;
|
||||
u32 ElementNameCount = read<u32>(m_Pointer); m_Pointer += 4;
|
||||
for (i = 0; i < ElementNameCount; ++i)
|
||||
m_ElementNames[ReadZStr8()] = i;
|
||||
|
||||
u32 AttributeNameCount = *(u32*)m_Pointer; m_Pointer += 4;
|
||||
u32 AttributeNameCount = read<u32>(m_Pointer); m_Pointer += 4;
|
||||
for (i = 0; i < AttributeNameCount; ++i)
|
||||
m_AttributeNames[ReadZStr8()] = i;
|
||||
#else
|
||||
// Ignore all the names for now, and skip over them
|
||||
// (remembering the position of the first)
|
||||
m_ElementNameCount = *(int*)m_Pointer; m_Pointer += 4;
|
||||
m_ElementNameCount = read<int>(m_Pointer); m_Pointer += 4;
|
||||
m_ElementPointer = m_Pointer;
|
||||
for (i = 0; i < m_ElementNameCount; ++i)
|
||||
m_Pointer += 4 + *(int*)m_Pointer; // skip over the string
|
||||
m_Pointer += 4 + read<int>(m_Pointer); // skip over the string
|
||||
|
||||
m_AttributeNameCount = *(int*)m_Pointer; m_Pointer += 4;
|
||||
m_AttributeNameCount = read<int>(m_Pointer); m_Pointer += 4;
|
||||
m_AttributePointer = m_Pointer;
|
||||
for (i = 0; i < m_AttributeNameCount; ++i)
|
||||
m_Pointer += 4 + *(int*)m_Pointer; // skip over the string
|
||||
m_Pointer += 4 + read<int>(m_Pointer); // skip over the string
|
||||
#endif
|
||||
|
||||
return true; // success
|
||||
@ -81,7 +87,7 @@ bool XMBFile::Initialise(const char* FileData)
|
||||
|
||||
std::string XMBFile::ReadZStr8()
|
||||
{
|
||||
int Length = *(int*)m_Pointer;
|
||||
int Length = read<int>(m_Pointer);
|
||||
m_Pointer += 4;
|
||||
std::string String (m_Pointer); // reads up until the first NULL
|
||||
m_Pointer += Length;
|
||||
@ -119,10 +125,10 @@ int XMBFile::GetElementID(const char* Name) const
|
||||
{
|
||||
// See if this could be the right string, checking its
|
||||
// length and then its contents
|
||||
if (*(int*)Pos == len && strncasecmp(Pos+4, Name, len) == 0)
|
||||
if (read<int>(Pos) == len && strncasecmp(Pos+4, Name, len) == 0)
|
||||
return i;
|
||||
// If not, jump to the next string
|
||||
Pos += 4 + *(int*)Pos;
|
||||
Pos += 4 + read<int>(Pos);
|
||||
}
|
||||
// Failed
|
||||
return -1;
|
||||
@ -139,10 +145,10 @@ int XMBFile::GetAttributeID(const char* Name) const
|
||||
{
|
||||
// See if this could be the right string, checking its
|
||||
// length and then its contents
|
||||
if (*(int*)Pos == len && strncasecmp(Pos+4, Name, len) == 0)
|
||||
if (read<int>(Pos) == len && strncasecmp(Pos+4, Name, len) == 0)
|
||||
return i;
|
||||
// If not, jump to the next string
|
||||
Pos += 4 + *(int*)Pos;
|
||||
Pos += 4 + read<int>(Pos);
|
||||
}
|
||||
// Failed
|
||||
return -1;
|
||||
@ -156,7 +162,7 @@ std::string XMBFile::GetElementString(const int ID) const
|
||||
{
|
||||
const char* Pos = m_ElementPointer;
|
||||
for (int i = 0; i < ID; ++i)
|
||||
Pos += 4 + *(int*)Pos;
|
||||
Pos += 4 + read<int>(Pos);
|
||||
return std::string(Pos+4);
|
||||
}
|
||||
|
||||
@ -164,7 +170,7 @@ std::string XMBFile::GetAttributeString(const int ID) const
|
||||
{
|
||||
const char* Pos = m_AttributePointer;
|
||||
for (int i = 0; i < ID; ++i)
|
||||
Pos += 4 + *(int*)Pos;
|
||||
Pos += 4 + read<int>(Pos);
|
||||
return std::string(Pos+4);
|
||||
}
|
||||
|
||||
@ -175,7 +181,7 @@ int XMBElement::GetNodeName() const
|
||||
if (m_Pointer == NULL)
|
||||
return -1;
|
||||
|
||||
return *(int*)(m_Pointer + 4); // == ElementName
|
||||
return read<int>(m_Pointer + 4); // == ElementName
|
||||
}
|
||||
|
||||
XMBElementList XMBElement::GetChildNodes() const
|
||||
@ -184,8 +190,8 @@ XMBElementList XMBElement::GetChildNodes() const
|
||||
return XMBElementList(NULL, 0);
|
||||
|
||||
return XMBElementList(
|
||||
m_Pointer + 20 + *(int*)(m_Pointer + 16), // == Children[]
|
||||
*(int*)(m_Pointer + 12) // == ChildCount
|
||||
m_Pointer + 20 + read<int>(m_Pointer + 16), // == Children[]
|
||||
read<int>(m_Pointer + 12) // == ChildCount
|
||||
);
|
||||
}
|
||||
|
||||
@ -195,15 +201,15 @@ XMBAttributeList XMBElement::GetAttributes() const
|
||||
return XMBAttributeList(NULL, 0);
|
||||
|
||||
return XMBAttributeList(
|
||||
m_Pointer + 24 + *(int*)(m_Pointer + 20), // == Attributes[]
|
||||
*(int*)(m_Pointer + 8) // == AttributeCount
|
||||
m_Pointer + 24 + read<int>(m_Pointer + 20), // == Attributes[]
|
||||
read<int>(m_Pointer + 8) // == AttributeCount
|
||||
);
|
||||
}
|
||||
|
||||
CStr8 XMBElement::GetText() const
|
||||
{
|
||||
// Return empty string if there's no text
|
||||
if (m_Pointer == NULL || *(int*)(m_Pointer + 20) == 0)
|
||||
if (m_Pointer == NULL || read<int>(m_Pointer + 20) == 0)
|
||||
return CStr8();
|
||||
|
||||
return CStr8(m_Pointer + 28);
|
||||
@ -212,10 +218,10 @@ CStr8 XMBElement::GetText() const
|
||||
int XMBElement::GetLineNumber() const
|
||||
{
|
||||
// Make sure there actually was some text to record the line of
|
||||
if (m_Pointer == NULL || *(int*)(m_Pointer + 20) == 0)
|
||||
if (m_Pointer == NULL || read<int>(m_Pointer + 20) == 0)
|
||||
return -1;
|
||||
else
|
||||
return *(int*)(m_Pointer + 24);
|
||||
return read<int>(m_Pointer + 24);
|
||||
}
|
||||
|
||||
XMBElement XMBElementList::GetFirstNamedItem(const int ElementName) const
|
||||
@ -226,8 +232,8 @@ XMBElement XMBElementList::GetFirstNamedItem(const int ElementName) const
|
||||
// fast enough with half a dozen attributes:
|
||||
for (int i = 0; i < Count; ++i)
|
||||
{
|
||||
int Length = *(int*)Pos;
|
||||
int Name = *(int*)(Pos+4);
|
||||
int Length = read<int>(Pos);
|
||||
int Name = read<int>(Pos+4);
|
||||
if (Name == ElementName)
|
||||
return XMBElement(Pos);
|
||||
Pos += Length;
|
||||
@ -247,14 +253,14 @@ XMBElement XMBElementList::Item(const int id)
|
||||
if (id == m_LastItemID+1)
|
||||
{
|
||||
Pos = m_LastPointer;
|
||||
Pos += *(int*)Pos; // skip over the last node
|
||||
Pos += read<int>(Pos); // skip over the last node
|
||||
}
|
||||
else
|
||||
{
|
||||
Pos = m_Pointer;
|
||||
// Skip over each preceding node
|
||||
for (int i=0; i<id; ++i)
|
||||
Pos += *(int*)Pos;
|
||||
Pos += read<int>(Pos);
|
||||
}
|
||||
// Cache information about this node
|
||||
m_LastItemID = id;
|
||||
@ -271,9 +277,9 @@ CStr8 XMBAttributeList::GetNamedItem(const int AttributeName) const
|
||||
// fast enough with half a dozen attributes:
|
||||
for (int i = 0; i < Count; ++i)
|
||||
{
|
||||
if (*(int*)Pos == AttributeName)
|
||||
if (read<int>(Pos) == AttributeName)
|
||||
return CStr8(Pos+8);
|
||||
Pos += 8 + *(int*)(Pos+4); // Skip over the string
|
||||
Pos += 8 + read<int>(Pos+4); // Skip over the string
|
||||
}
|
||||
|
||||
// Can't find attribute
|
||||
@ -291,18 +297,18 @@ XMBAttribute XMBAttributeList::Item(const int id)
|
||||
{
|
||||
Pos = m_LastPointer;
|
||||
// Skip over the last attribute
|
||||
Pos += 8 + *(int*)(Pos+4);
|
||||
Pos += 8 + read<int>(Pos+4);
|
||||
}
|
||||
else
|
||||
{
|
||||
Pos = m_Pointer;
|
||||
// Skip over each preceding attribute
|
||||
for (int i=0; i<id; ++i)
|
||||
Pos += 8 + *(int*)(Pos+4); // skip ID, length, and string data
|
||||
Pos += 8 + read<int>(Pos+4); // skip ID, length, and string data
|
||||
}
|
||||
// Cache information about this attribute
|
||||
m_LastItemID = id;
|
||||
m_LastPointer = Pos;
|
||||
|
||||
return XMBAttribute(*(int*)Pos, CStr8(Pos+8));
|
||||
return XMBAttribute(read<int>(Pos), CStr8(Pos+8));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user