Verify file read errors during database loading 51/185951/4
authorLukasz Wojciechowski <l.wojciechow@partner.samsung.com>
Thu, 2 Aug 2018 18:48:35 +0000 (20:48 +0200)
committerLukasz Wojciechowski <l.wojciechow@partner.samsung.com>
Wed, 8 Aug 2018 11:18:53 +0000 (13:18 +0200)
Verify if there are no IO errors during database loading from files.

Change-Id: I49ac887bae05f47b2b75dd6dc6489fc4d54562fb
Signed-off-by: Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
src/common/exceptions/DatabaseReadException.h [new file with mode: 0644]
src/storage/BucketDeserializer.cpp
src/storage/BucketDeserializer.h
src/storage/ChecksumValidator.cpp
src/storage/InMemoryStorageBackend.cpp
src/storage/StorageDeserializer.cpp

diff --git a/src/common/exceptions/DatabaseReadException.h b/src/common/exceptions/DatabaseReadException.h
new file mode 100644 (file)
index 0000000..e4c3f7e
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ * @file        src/common/exceptions/DatabaseReadException.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file defines exception thrown when database read fails
+ */
+
+#ifndef SRC_COMMON_EXCEPTIONS_DATABASEREADEXCEPTION_H_
+#define SRC_COMMON_EXCEPTIONS_DATABASEREADEXCEPTION_H_
+
+#include <string>
+
+#include <exceptions/DatabaseException.h>
+
+namespace Cynara {
+
+class DatabaseReadException : public DatabaseException {
+public:
+    DatabaseReadException(const std::string &filename, const std::string &operation)
+     : m_message("Loading the database from the file <" + filename + "> failed during " + operation) {};
+    virtual ~DatabaseReadException() {};
+
+    const std::string &message(void) const {
+        return m_message;
+    }
+
+private:
+    std::string m_message;
+};
+
+} /* namespace Cynara */
+
+#endif /* SRC_COMMON_EXCEPTIONS_DATABASEREADEXCEPTION_H_ */
index 6c4a88ba3afa9b83f828aeec7dde53a2dcb88d28..24e6b33e0c85c3210adab2964d90c35bba3da54b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
 
 #include <config/PathConfig.h>
 #include <exceptions/BucketRecordCorruptedException.h>
+#include <exceptions/DatabaseReadException.h>
 #include <types/PolicyCollection.h>
 #include <types/PolicyResult.h>
 #include <types/PolicyType.h>
@@ -40,12 +41,11 @@ namespace Cynara {
 PolicyCollection BucketDeserializer::loadPolicies(void) {
     PolicyCollection policies;
 
-    // TODO: Get someone smart to do error checking on stream
     std::string line;
     std::size_t lineNum = 1;
-    while(std::getline(*m_inStream, line, PathConfig::StoragePath::recordSeparator)) {
+    while (std::getline(*m_inStream, line, PathConfig::StoragePath::recordSeparator)) {
         if (line.empty())
-            break;
+            continue;
 
         try {
             std::size_t beginToken = 0;
@@ -59,6 +59,9 @@ PolicyCollection BucketDeserializer::loadPolicies(void) {
         }
         ++lineNum;
     }
+    if (m_inStream->fail() && !m_inStream->eof()) {
+        throw DatabaseReadException(m_filename, "reading line " + std::to_string(lineNum));
+    }
 
     return policies;
 }
index 666e14e9ee2d77e3dc09b5408f91e9c80825095e..d2162ad03634a3b6aa4174b83c6cef9f6a39a8bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -34,7 +34,8 @@ namespace Cynara {
 class BucketDeserializer {
 
 public:
-    BucketDeserializer(std::shared_ptr<std::istream> inStream) : m_inStream(inStream) {
+    BucketDeserializer(std::shared_ptr<std::istream> inStream, const std::string &filename = std::string())
+     : m_inStream(inStream), m_filename(filename) {
     }
 
     PolicyCollection loadPolicies(void);
@@ -42,6 +43,7 @@ public:
 
 private:
     std::shared_ptr<std::istream> m_inStream;
+    std::string m_filename;
 };
 
 } /* namespace Cynara */
index 561f09877cf8becdfaf3112372dd77d3ec94487a..962b667c1f486445cccba596e04e3d20bbd0006d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
 #include <memory>
 #include <new>
 #include <sstream>
+#include <string>
 
 #include <config/PathConfig.h>
 #include <exceptions/ChecksumRecordCorruptedException.h>
+#include <exceptions/DatabaseReadException.h>
 #include <exceptions/UnexpectedErrorException.h>
 #include <log/log.h>
 #include <md5wrapper.h>
@@ -55,6 +57,9 @@ void ChecksumValidator::load(std::istream &stream) {
             throw ex.withLineNumber(lineNum);
         }
     }
+    if (stream.fail() && !stream.eof()) {
+        throw DatabaseReadException(PathConfig::StoragePath::checksumFilename, "reading line " + std::to_string(lineNum));
+    }
 };
 
 const std::string ChecksumValidator::generate(const std::string &data) {
@@ -91,6 +96,9 @@ void ChecksumValidator::compare(std::istream &stream, const std::string &pathnam
               std::istreambuf_iterator<char>(),
               std::ostreambuf_iterator<char>(copyStream));
     stream.seekg(0);
+    if (stream.fail() && !stream.eof()) {
+        throw DatabaseReadException(filename, "making a copy for checksum validation");
+    }
 
     if (m_sums[filename] != generate(copyStream.str())) {
         throw ChecksumRecordCorruptedException(m_sums[filename]);
index 8ca7a0735b3aadd27047d27daa0134f21e26166f..f82d3f2ddf05c122431ad5705a7311149219a705 100644 (file)
@@ -263,7 +263,7 @@ std::shared_ptr<BucketDeserializer> InMemoryStorageBackend::bucketStreamOpener(
     auto bucketStream = std::make_shared<std::ifstream>();
     try {
         openFileStream(*bucketStream, bucketFilename, isBackupValid);
-        return std::make_shared<BucketDeserializer>(bucketStream);
+        return std::make_shared<BucketDeserializer>(bucketStream, bucketFilename);
     } catch (const FileNotFoundException &) {
         return nullptr;
     } catch (const std::bad_alloc &) {
index 3a8c913e479adc25ede59ec297a88d213a0d21a3..4266c3121a5da28562fbf5f5947b80fb6c37710d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
 #include <config/PathConfig.h>
 #include <exceptions/BucketDeserializationException.h>
 #include <exceptions/BucketRecordCorruptedException.h>
+#include <exceptions/DatabaseReadException.h>
 #include <types/PolicyType.h>
 
 #include <storage/BucketDeserializer.h>
@@ -48,7 +49,7 @@ void StorageDeserializer::initBuckets(Buckets &buckets) {
     std::string line;
     while (std::getline(*m_inStream, line, PathConfig::StoragePath::recordSeparator)) {
         if (line.empty())
-            break;
+            continue;
 
         std::size_t beginToken = 0;
         auto bucketId = parseBucketId(line, beginToken);
@@ -59,6 +60,9 @@ void StorageDeserializer::initBuckets(Buckets &buckets) {
         buckets.insert({ bucketId, PolicyBucket(bucketId, PolicyResult(policyType, metadata)) });
         ++lineNum;
     }
+    if (m_inStream->fail() && !m_inStream->eof()) {
+        throw DatabaseReadException(PathConfig::StoragePath::indexFilename, "reading line " + std::to_string(lineNum));
+    }
 }
 
 void StorageDeserializer::loadBuckets(Buckets &buckets) {