@@ -62,28 +62,28 @@ namespace hkLib {
6262 // / header of tree as stored in file
6363 // / </summary>
6464 struct TreeRoot {
65- uint32_t Magic, // !< magic nummber MagicNumber or SwappedMagicNumber
65+ std:: uint32_t Magic, // !< magic nummber MagicNumber or SwappedMagicNumber
6666 nLevels, // !< number of tree levels
6767 LevelSizes[1 ]; // !< variable length array (nLevels entries with size of level data in bytes)
6868 };
6969
70- void hkTree::LoadToNode (hkTreeNode* parent, hkTreeNode& node, char ** pdata, int level)
70+ void hkLib:: hkTree::LoadToNode (hkTreeNode* parent, hkTreeNode& node, char ** pdata, char * data_end , int level)
7171 {
7272 node.tree = this ;
7373 auto size = static_cast <std::size_t >(LevelSizes.at (level));
7474 node.level = level;
75- // node.len = size;
7675 node.isSwapped = isSwapped;
7776 node.Parent = parent;
78- node.Data = std::span ( *pdata, size );
77+ node.Data = std::span (*pdata, size);
7978 *pdata += size;
80- uint32_t nchildren;
81- std::memcpy (&nchildren, *pdata, sizeof (uint32_t ));
79+ std::uint32_t nchildren;
80+ if (*pdata + sizeof (std::uint32_t ) >= data_end) throw std::runtime_error (" not enough data" );
81+ std::memcpy (&nchildren, *pdata, sizeof (std::uint32_t ));
8282 if (isSwapped) { swapInPlace (nchildren); }
83- *pdata += sizeof (uint32_t );
83+ *pdata += sizeof (std:: uint32_t );
8484 node.Children .resize (nchildren);
8585 for (auto & child : node.Children ) {
86- LoadToNode (&node, child, pdata, level + 1 );
86+ LoadToNode (&node, child, pdata, data_end, level + 1 );
8787 }
8888 }
8989
@@ -103,6 +103,7 @@ namespace hkLib {
103103
104104 bool hkTree::InitFromBuffer (const std::string_view& id, char * buffer, std::size_t len)
105105 {
106+ if (len < sizeof (TreeRoot)) throw std::runtime_error (" invalid TreeRoot (too few bytes in file)" );
106107 ID = id;
107108 TreeRoot* root = reinterpret_cast <TreeRoot*>(buffer); // we assume buffer is correctly aligned
108109 isSwapped = false ;
@@ -116,12 +117,14 @@ namespace hkLib {
116117 if (isSwapped) {
117118 swapInPlace (root->nLevels );
118119 }
120+ const auto root_bytes = offsetof (TreeRoot, LevelSizes) + sizeof (std::uint32_t ) * root->nLevels ;
121+ if (len < root_bytes) throw std::runtime_error (" invalid TreeRoot (too few bytes in file)" );
119122 for (std::size_t i = 0 ; i < root->nLevels ; ++i) {
120123 if (isSwapped) { swapInPlace (root->LevelSizes [i]); }
121124 LevelSizes.push_back (root->LevelSizes [i]);
122125 }
123- char * data = buffer + offsetof (TreeRoot, LevelSizes) + sizeof ( uint32_t ) * root-> nLevels ; // start of first tree node
124- LoadToNode (nullptr , RootNode, &data, 0 );
126+ char * data = buffer + root_bytes ; // start of first tree node
127+ LoadToNode (nullptr , RootNode, &data, data + len, 0 );
125128 if (data - buffer != static_cast <std::ptrdiff_t >(len)) {
126129 throw std::runtime_error (" bytes read != bytes in buffer" );
127130 }
0 commit comments