From: Yehor Velykozhon -X (yvelykoz - SOFTSERVE INC at Cisco) Date: Tue, 14 Nov 2023 16:43:49 +0000 (+0000) Subject: Pull request #4091: olefile: replace hash map with list to guarantee order X-Git-Tag: 3.1.75.0~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=060504ce1ceb04e7444a76f4f254a5cee1317661;p=thirdparty%2Fsnort3.git Pull request #4091: olefile: replace hash map with list to guarantee order Merge in SNORT/snort3 from ~YVELYKOZ/snort3:vba_update to master Squashed commit of the following: commit aec621ae92f61804664b1a0172b0dd0594201c68 Author: Yehor Velykozhon Date: Wed Nov 1 14:33:25 2023 +0200 decompress: use list for OLE file entries to guarantee their order in file_data --- diff --git a/src/decompress/file_olefile.cc b/src/decompress/file_olefile.cc index 5c7bed68f..ac8917562 100644 --- a/src/decompress/file_olefile.cc +++ b/src/decompress/file_olefile.cc @@ -26,11 +26,11 @@ DirectoryList :: ~DirectoryList() { - std::unordered_map::iterator it = oleentry.begin(); + auto it = oleentry.begin(); while (it != oleentry.end()) { - FileProperty* node = it->second; + FileProperty* node = *it; delete[] node->get_name(); delete node; it = oleentry.erase(it); @@ -119,6 +119,7 @@ void OleFile :: walk_directory_list() if (strcmp(file_name, ROOT_ENTRY) == 0) dir_list->set_mini_stream_sector(node->get_starting_sector()); + object_type type = node->get_file_type(); // check for all the empty/non valid entries in the directory list. if (!(type == ROOT_STORAGE or type == STORAGE or type == STREAM)) @@ -127,7 +128,7 @@ void OleFile :: walk_directory_list() delete[] name_buf; } else - dir_list->oleentry.insert({ file_name, node }); + dir_list->oleentry.emplace_back(node); count++; } // Reading the next sector of current_sector by referring the FAT list array. @@ -145,13 +146,16 @@ void OleFile :: walk_directory_list() FileProperty* DirectoryList :: get_file_node(char* name) { - std::unordered_map::iterator it; + auto it = std::find_if(oleentry.begin(), oleentry.end(), + [name](const auto& curr) + { + return !strcmp(curr->get_name(), name); + }); - it = oleentry.find(name); + if (it == oleentry.end()) + return nullptr; - if (it != oleentry.end()) - return(it->second); - return nullptr; + return *it; } // Every index of fat_list array is the fat sector ID and the value present @@ -271,9 +275,8 @@ uint32_t OleFile :: find_bytes_to_copy(uint32_t byte_offset, uint32_t data_len, return bytes_to_copy; } -void OleFile :: get_file_data(char* file, uint8_t*& file_data, uint32_t& data_len) +void OleFile :: get_file_data(FileProperty* node, uint8_t*& file_data, uint32_t& data_len) { - FileProperty* node = dir_list->get_file_node(file); data_len = 0; if (node) @@ -661,19 +664,19 @@ void OleFile :: decompression(const uint8_t* data, uint32_t& data_len, uint8_t*& // Function to extract the VBA data and send it for RLE decompression. void OleFile :: find_and_extract_vba(uint8_t*& vba_buf, uint32_t& vba_buf_len) { - std::unordered_map::iterator it = dir_list->oleentry.begin(); + auto it = dir_list->oleentry.begin(); uint32_t vba_buffer_offset = 0; vba_buf = new uint8_t[MAX_VBA_BUFFER_LEN + 1](); while (it != dir_list->oleentry.end()) { - FileProperty* node = it->second; + FileProperty* node = *it; ++it; if (node->get_file_type() == STREAM) { uint8_t* data = nullptr; uint32_t data_len; - get_file_data(node->get_name(), data, data_len); + get_file_data(node, data, data_len); uint8_t* data1 = data; int32_t offset = get_file_offset(data, data_len); if (offset <= 0) diff --git a/src/decompress/file_olefile.h b/src/decompress/file_olefile.h index 898c4b4fd..3f4d7667d 100644 --- a/src/decompress/file_olefile.h +++ b/src/decompress/file_olefile.h @@ -197,7 +197,7 @@ private: class DirectoryList { public: - std::unordered_map oleentry; + std::list oleentry; snort::UtfDecodeSession* utf_state = nullptr; bool is_file_exists(char* name); @@ -235,7 +235,6 @@ public: int32_t get_fat_offset(int32_t sec_id); int32_t get_mini_fat_offset(int32_t sec_id); int32_t get_file_offset(const uint8_t*, uint32_t data_len); - void get_file_data(char*, uint8_t*&, uint32_t&); void decompression(const uint8_t* data, uint32_t& data_len, uint8_t*& buffer, uint32_t& buffer_ofset); @@ -261,7 +260,9 @@ public: delete[] mini_fat_list; } + private: + void get_file_data(FileProperty*, uint8_t*&, uint32_t&); const uint8_t* file_buf; uint32_t buf_len;