2020#include " common/tsfile_common.h"
2121
2222#include < algorithm>
23+ #include < limits>
2324#include < map>
2425
2526#include " common/logger/elog.h"
@@ -180,37 +181,101 @@ int TSMIterator::get_next(std::shared_ptr<IDeviceID>& ret_device_id,
180181 return ret;
181182}
182183
183- int TsFileMeta::serialize_to (common::ByteStream& out) {
184+ int TsFileMeta::serialize_to (common::ByteStream& out,
185+ int32_t & serialized_size) {
186+ serialized_size = 0 ;
187+ const size_t max_property_size =
188+ static_cast <size_t >(std::numeric_limits<int32_t >::max ());
189+ if (tsfile_properties_.size () > max_property_size) {
190+ return common::E_OUT_OF_RANGE ;
191+ }
192+ for (const auto & tsfile_property : tsfile_properties_) {
193+ if (tsfile_property.first .size () > max_property_size ||
194+ (!tsfile_property.second .is_null &&
195+ tsfile_property.second .value .size () > max_property_size)) {
196+ return common::E_OUT_OF_RANGE ;
197+ }
198+ }
199+
200+ int ret = common::E_OK ;
184201 auto start_idx = out.total_size ();
185- common::SerializationUtil::write_var_uint (
186- table_metadata_index_node_map_.size (), out);
202+ if (RET_FAIL (common::SerializationUtil::write_var_uint (
203+ table_metadata_index_node_map_.size (), out))) {
204+ return ret;
205+ }
187206 for (auto & idx_nodes_iter : table_metadata_index_node_map_) {
188- common::SerializationUtil::write_var_str (idx_nodes_iter.first , out);
189- idx_nodes_iter.second ->serialize_to (out);
207+ if (RET_FAIL (common::SerializationUtil::write_var_str (
208+ idx_nodes_iter.first , out))) {
209+ return ret;
210+ } else if (RET_FAIL (idx_nodes_iter.second ->serialize_to (out))) {
211+ return ret;
212+ }
190213 }
191214
192- common::SerializationUtil::write_var_uint (table_schemas_.size (), out);
215+ if (RET_FAIL (common::SerializationUtil::write_var_uint (
216+ table_schemas_.size (), out))) {
217+ return ret;
218+ }
193219 for (auto & table_schema_iter : table_schemas_) {
194- common::SerializationUtil::write_var_str (table_schema_iter.first , out);
195- table_schema_iter.second ->serialize_to (out);
220+ if (RET_FAIL (common::SerializationUtil::write_var_str (
221+ table_schema_iter.first , out))) {
222+ return ret;
223+ } else if (RET_FAIL (table_schema_iter.second ->serialize_to (out))) {
224+ return ret;
225+ }
196226 }
197227
198- common::SerializationUtil::write_i64 (meta_offset_, out);
228+ if (RET_FAIL (common::SerializationUtil::write_i64 (meta_offset_, out))) {
229+ return ret;
230+ }
199231
200232 if (bloom_filter_ != nullptr ) {
201- bloom_filter_->serialize_to (out);
233+ if (RET_FAIL (bloom_filter_->serialize_to (out))) {
234+ return ret;
235+ }
202236 } else {
203- common::SerializationUtil::write_ui8 (0 , out);
237+ if (RET_FAIL (common::SerializationUtil::write_ui8 (0 , out))) {
238+ return ret;
239+ }
204240 }
205241
206- common::SerializationUtil::write_var_int (tsfile_properties_.size (), out);
242+ if (RET_FAIL (common::SerializationUtil::write_var_int (
243+ static_cast <int32_t >(tsfile_properties_.size ()), out))) {
244+ return ret;
245+ }
207246 for (const auto & tsfile_property : tsfile_properties_) {
208- common::SerializationUtil::write_var_str (tsfile_property.first , out);
209- common::SerializationUtil::write_var_char_ptr (tsfile_property.second ,
210- out);
247+ if (RET_FAIL (common::SerializationUtil::write_var_str (
248+ tsfile_property.first , out))) {
249+ return ret;
250+ }
251+ const TsFilePropertyValue& value = tsfile_property.second ;
252+ if (value.is_null ) {
253+ if (RET_FAIL (common::SerializationUtil::write_var_int (
254+ NO_STR_TO_READ , out))) {
255+ return ret;
256+ }
257+ } else {
258+ if (RET_FAIL (common::SerializationUtil::write_var_int (
259+ static_cast <int32_t >(value.value .size ()), out))) {
260+ return ret;
261+ }
262+ if (!value.value .empty ()) {
263+ if (RET_FAIL (out.write_buf (
264+ value.value .data (),
265+ static_cast <uint32_t >(value.value .size ())))) {
266+ return ret;
267+ }
268+ }
269+ }
211270 }
212271
213- return out.total_size () - start_idx;
272+ const uint64_t total_size = out.total_size () - start_idx;
273+ if (total_size >
274+ static_cast <uint64_t >(std::numeric_limits<int32_t >::max ())) {
275+ return common::E_OUT_OF_RANGE ;
276+ }
277+ serialized_size = static_cast <int32_t >(total_size);
278+ return common::E_OK ;
214279}
215280
216281int TsFileMeta::deserialize_from (common::ByteStream& in) {
@@ -251,15 +316,67 @@ int TsFileMeta::deserialize_from(common::ByteStream& in) {
251316
252317 common::SerializationUtil::read_i64 (meta_offset_, in);
253318
254- bloom_filter_->deserialize_from (in);
319+ if (RET_FAIL (bloom_filter_->deserialize_from (in))) {
320+ return ret;
321+ }
255322
256323 int32_t tsfile_properties_size = 0 ;
257- common::SerializationUtil::read_var_int (tsfile_properties_size, in);
324+ if (RET_FAIL (common::SerializationUtil::read_var_int (tsfile_properties_size,
325+ in))) {
326+ return ret;
327+ }
328+ if (tsfile_properties_size < 0 ) {
329+ return common::E_TSFILE_CORRUPTED ;
330+ }
258331 for (int i = 0 ; i < tsfile_properties_size; i++) {
259- std::string key, *value;
260- common::SerializationUtil::read_var_str (key, in);
261- common::SerializationUtil::read_var_char_ptr (value, in);
262- tsfile_properties_.emplace (key, value);
332+ std::string key;
333+ int32_t key_len = 0 ;
334+ int32_t value_len = 0 ;
335+ if (RET_FAIL (common::SerializationUtil::read_var_int (key_len, in))) {
336+ return ret;
337+ } else if (key_len < 0 ) {
338+ return common::E_TSFILE_CORRUPTED ;
339+ }
340+ if (static_cast <uint64_t >(key_len) > in.remaining_size ()) {
341+ return common::E_TSFILE_CORRUPTED ;
342+ }
343+ key.resize (static_cast <size_t >(key_len));
344+ if (key_len > 0 ) {
345+ uint32_t read_len = 0 ;
346+ if (RET_FAIL (in.read_buf (reinterpret_cast <uint8_t *>(&key[0 ]),
347+ static_cast <uint32_t >(key_len),
348+ read_len))) {
349+ return ret;
350+ } else if (read_len != static_cast <uint32_t >(key_len)) {
351+ return common::E_BUF_NOT_ENOUGH ;
352+ }
353+ }
354+ if (RET_FAIL (common::SerializationUtil::read_var_int (value_len, in))) {
355+ return ret;
356+ }
357+
358+ TsFilePropertyValue value;
359+ if (value_len == NO_STR_TO_READ ) {
360+ value.is_null = true ;
361+ } else if (value_len < 0 ) {
362+ return common::E_TSFILE_CORRUPTED ;
363+ } else {
364+ if (static_cast <uint64_t >(value_len) > in.remaining_size ()) {
365+ return common::E_TSFILE_CORRUPTED ;
366+ }
367+ value.is_null = false ;
368+ value.value .resize (static_cast <size_t >(value_len));
369+ if (value_len > 0 ) {
370+ uint32_t read_len = 0 ;
371+ if (RET_FAIL (
372+ in.read_buf (value.value .data (), value_len, read_len))) {
373+ return ret;
374+ } else if (read_len != static_cast <uint32_t >(value_len)) {
375+ return common::E_BUF_NOT_ENOUGH ;
376+ }
377+ }
378+ }
379+ tsfile_properties_.emplace (key, std::move (value));
263380 }
264381 return ret;
265382}
@@ -375,4 +492,4 @@ int MetaIndexNode::binary_search_children(const String &name,
375492}
376493#endif
377494
378- } // end namespace storage
495+ } // end namespace storage
0 commit comments