Commit b0e46085 for tesseract

commit b0e46085f48d206797ad36ba643dbe9f12ad157a
Author: Stefan Weil <sw@weilnetz.de>
Date:   Tue Jan 12 21:23:14 2021 +0100

    Fix serialization of std::vector (fix issue #3220)

    Signed-off-by: Stefan Weil <sw@weilnetz.de>

diff --git a/src/ccutil/serialis.cpp b/src/ccutil/serialis.cpp
index 20f71769..12e31594 100644
--- a/src/ccutil/serialis.cpp
+++ b/src/ccutil/serialis.cpp
@@ -73,6 +73,42 @@ TFile::~TFile() {
     delete data_;
 }

+template <typename T>
+bool TFile::DeSerialize(std::vector<T>& data) {
+  uint32_t size;
+  if (!DeSerialize(&size)) {
+    return false;
+  }
+  // Arbitrarily limit the number of elements to protect against bad data.
+  const uint32_t limit = 50000000;
+  assert(size <= limit);
+  if (size > limit) {
+    return false;
+  } else if (size > 0) {
+    // TODO: optimize.
+    data.reserve(size);
+    return DeSerialize(&data[0], size);
+  }
+  data.clear();
+  return true;
+}
+
+template <typename T>
+bool TFile::Serialize(const std::vector<T>& data) {
+  uint32_t size = data.size();
+  if (!Serialize(&size)) {
+    return false;
+  } else if (size > 0) {
+    return Serialize(&data[0], size);
+  }
+  return true;
+}
+
+template bool TFile::DeSerialize(std::vector<double>& data);
+template bool TFile::DeSerialize(std::vector<int32_t>& data);
+template bool TFile::Serialize(const std::vector<double>& data);
+template bool TFile::Serialize(const std::vector<int32_t>& data);
+
 bool TFile::DeSerialize(std::vector<char>& data) {
   uint32_t size;
   if (!DeSerialize(&size)) {
@@ -91,7 +127,7 @@ bool TFile::Serialize(const std::vector<char>& data) {
   if (!Serialize(&size)) {
     return false;
   } else if (size > 0) {
-  return Serialize(&data[0], size);
+    return Serialize(&data[0], size);
   }
   return true;
 }
diff --git a/src/ccutil/serialis.h b/src/ccutil/serialis.h
index f52948fc..9d17bd3e 100644
--- a/src/ccutil/serialis.h
+++ b/src/ccutil/serialis.h
@@ -86,6 +86,7 @@ class TESS_API TFile {

   // Deserialize data.
   bool DeSerialize(std::vector<char>& data);
+  template <typename T> bool DeSerialize(std::vector<T>& data);
   template <typename T>
   bool DeSerialize(T *data, size_t count = 1) {
       return FReadEndian(data, sizeof(T), count) == count;
@@ -93,39 +94,12 @@ class TESS_API TFile {

   // Serialize data.
   bool Serialize(const std::vector<char>& data);
+  template <typename T> bool Serialize(const std::vector<T>& data);
   template <typename T>
   bool Serialize(const T *data, size_t count = 1) {
       return FWrite(data, sizeof(T), count) == count;
   }

-  template <typename T>
-  bool Serialize(const std::vector<T>& data) {
-    auto size_used_ = data.size();
-    if (FWrite(&size_used_, sizeof(size_used_), 1) != 1) {
-      return false;
-    }
-    if (FWrite(data.data(), sizeof(T), size_used_) != size_used_) {
-      return false;
-    }
-    return true;
-  }
-
-  template <typename T>
-  bool DeSerialize(std::vector<T>& data) {
-    uint32_t reserved;
-    if (FReadEndian(&reserved, sizeof(reserved), 1) != 1) {
-      return false;
-    }
-    // Arbitrarily limit the number of elements to protect against bad data.
-    const uint32_t limit = 50000000;
-    //assert(reserved <= limit);
-    if (reserved > limit) {
-      return false;
-    }
-    data.reserve(reserved);
-    return FReadEndian(data.data(), sizeof(T), reserved) == reserved;
-  }
-
   // Skip data.
   bool Skip(size_t count);