Cleanup and securing XMLElementEncode and DecodeArray

This commit is contained in:
brunoherbelin
2021-01-10 09:52:58 +01:00
parent 6b5ccb4450
commit fe54afbe1c
2 changed files with 45 additions and 40 deletions

View File

@@ -118,7 +118,7 @@ void tinyxml2::XMLElementToGLM(XMLElement *elem, glm::mat4 &matrix)
} }
XMLElement *tinyxml2::XMLElementEncodeArray(XMLDocument *doc, void *array, unsigned int arraysize) XMLElement *tinyxml2::XMLElementEncodeArray(XMLDocument *doc, const void *array, uint arraysize)
{ {
// create <array> node // create <array> node
XMLElement *newelement = doc->NewElement( "array" ); XMLElement *newelement = doc->NewElement( "array" );
@@ -157,63 +157,68 @@ XMLElement *tinyxml2::XMLElementEncodeArray(XMLDocument *doc, void *array, unsig
return newelement; return newelement;
} }
bool tinyxml2::XMLElementDecodeArray(XMLElement *elem, void *array, unsigned int arraysize) bool tinyxml2::XMLElementDecodeArray(XMLElement *elem, void *array, uint arraysize)
{ {
bool ret = false; bool ret = false;
// sanity check
if (array==nullptr || arraysize==0)
return ret;
// make sure we have the good type of XML node // make sure we have the good type of XML node
if ( !elem || std::string(elem->Name()).compare("array") != 0 ) if ( !elem || std::string(elem->Name()).compare("array") != 0 )
return ret; return ret;
// make sure the stored array is of the requested array size // make sure the stored array is of the requested array size
unsigned int len = 0; uint len = 0;
elem->QueryUnsignedAttribute("len", &len); elem->QueryUnsignedAttribute("len", &len);
if ( arraysize != len ) if (len == arraysize)
return ret; {
// read and decode the text field in <array>
gsize decoded_size = 0;
guchar *decoded_array = g_base64_decode(elem->GetText(), &decoded_size);
// read and decode the text field in <array> // if data is z-compressed (zbytes size is indicated)
gsize decoded_size = 0; uint zbytes = 0;
guchar *decoded_array = g_base64_decode(elem->GetText(), &decoded_size); elem->QueryUnsignedAttribute("zbytes", &zbytes);
if ( zbytes > 0) {
// sanity check 1: decoded data size must match the buffer size
if ( decoded_array && zbytes == (uint) decoded_size ) {
// if data is z-compressed (zbytes size is indicated) // allocate a temporary array for decompressing data
uint zbytes = 0; uLong uncompressed_size = len;
elem->QueryUnsignedAttribute("zbytes", &zbytes); gchar *uncompressed_array = g_new(gchar, uncompressed_size);
if ( zbytes > 0) {
// sanity check 1: decoded data size must match the buffer size
if ( decoded_array && zbytes == (uint) decoded_size ) {
// allocate a temporary array for decompressing data // zlib uncompress ((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
uLong uncompressed_size = arraysize; uncompress((Bytef *)uncompressed_array, &uncompressed_size,
gchar *uncompressed_array = g_new(gchar, uncompressed_size); (Bytef *)decoded_array, (uLong) zbytes) ;
// zlib uncompress ((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); // sanity check 2: decompressed data size must match array size
uncompress((Bytef *)uncompressed_array, &uncompressed_size, if ( uncompressed_array && len == uncompressed_size ){
(Bytef *)decoded_array, (uLong) zbytes) ; // copy to target array
memcpy(array, uncompressed_array, len);
// sanity check 2: decompressed data size must match array size // success
if ( uncompressed_array && arraysize == uncompressed_size ){ ret = true;
}
// free temp decompression buffer
g_free(uncompressed_array);
}
}
// data is not z-compressed
else {
// copy the decoded data
if ( decoded_array && len == decoded_size ) {
// copy to target array // copy to target array
memcpy(array, uncompressed_array, arraysize); memcpy(array, decoded_array, len);
// success // success
ret = true; ret = true;
} }
// free temp decompression buffer
g_free(uncompressed_array);
} }
}
// data is not z-compressed
else {
// copy the decoded data
if ( decoded_array && arraysize == decoded_size )
memcpy(array, decoded_array, arraysize);
// success
ret = true;
}
// free temporary array // free temporary array
g_free(decoded_array); g_free(decoded_array);
}
return ret; return ret;
} }

View File

@@ -21,8 +21,8 @@ void XMLElementToGLM(XMLElement *elem, glm::vec3 &vector);
void XMLElementToGLM(XMLElement *elem, glm::vec4 &vector); void XMLElementToGLM(XMLElement *elem, glm::vec4 &vector);
void XMLElementToGLM(XMLElement *elem, glm::mat4 &matrix); void XMLElementToGLM(XMLElement *elem, glm::mat4 &matrix);
XMLElement *XMLElementEncodeArray(XMLDocument *doc, void *array, unsigned int arraysize); XMLElement *XMLElementEncodeArray(XMLDocument *doc, const void *array, uint arraysize);
bool XMLElementDecodeArray(XMLElement *elem, void *array, unsigned int arraysize); bool XMLElementDecodeArray(XMLElement *elem, void *array, uint arraysize);
bool XMLSaveDoc(tinyxml2::XMLDocument * const doc, std::string filename); bool XMLSaveDoc(tinyxml2::XMLDocument * const doc, std::string filename);
bool XMLResultError(int result); bool XMLResultError(int result);