Use proper numeric types in ext4 tool 88/193688/6
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Tue, 2 Oct 2018 08:07:10 +0000 (10:07 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 29 Nov 2018 16:04:21 +0000 (17:04 +0100)
Modify the numeric types used to represent filesystem features to solve
the problem of unnecessary casts, loss of precision and possible integer
overflow.

Simplify few related parts:
- Add template function in ProgressBar to handle different integer
  types.
- Move duplicated fast encryption logic inside copyInPlace.
- Remove unnecessary variables and calculations from
  Ext4Tool::readInfo().

Change-Id: Id4fc83390e9b26cc84fcb7e08cde6e467a6a93c4

18 files changed:
fota/fota.cpp
server/engine/encryption/dmcrypt-engine.cpp
server/engine/encryption/ecryptfs-engine.cpp
server/engine/encryption/ext4-engine.cpp
server/engine/erase/erase-engine.cpp
server/engine/erase/erase-engine.h
server/engine/erase/mmc-engine.cpp
server/engine/erase/mmc-engine.h
server/ext4-tool.cpp
server/ext4-tool.h
server/external-encryption.cpp
server/internal-encryption.cpp
server/progress-bar.cpp
server/progress-bar.h
server/secure-erase.cpp
tests/dmcrypt-engine.cpp
tests/ecryptfs-engine.cpp
tests/ext4-engine.cpp

index c747af7..ccbdafe 100644 (file)
@@ -33,8 +33,7 @@ namespace ode {
 ProgressBar::ProgressBar(UpdateFunc const&) : updateValue(0) {}
 ProgressBar::~ProgressBar() {}
 
-void ProgressBar::update(int) {}
-void ProgressBar::update(int, int, int) {}
+void ProgressBar::update(unsigned) {}
 void ProgressBar::done(void) {}
 
 } // namespace ode
@@ -71,7 +70,7 @@ int main(int argc, char* argv[])
                if (MOUNT == argv[1]) {
                        auto masterKey = UpgradeSupport::loadMasterKey(DEV_PATH);
 
-                       DMCryptEngine dmcrypt(DEV_PATH, INTERNAL_PATH, ProgressBar([](int){}));
+                       DMCryptEngine dmcrypt(DEV_PATH, INTERNAL_PATH, ProgressBar([](unsigned){}));
 
                        // mount options are ignored by mount()
                        dmcrypt.mount(masterKey, 0);
index 838816a..e8d8d9e 100644 (file)
@@ -44,18 +44,18 @@ namespace ode {
 
 namespace {
 
-blkcnt_t getBlockCount(const std::string &src)
+unsigned long getBlockCount(const std::string &src)
 {
        int fd = open(src.c_str(), O_RDONLY);
        if (fd < 0)
                return 0;
 
-       unsigned long long size = 0;
+       unsigned long size = 0;
        if ((ioctl(fd, BLKGETSIZE, &size)) == -1)
                size = 0;
        close(fd);
 
-       return (blkcnt_t)size;
+       return size;
 }
 
 const std::string convertToHex(const BinaryData &binary)
@@ -237,20 +237,28 @@ BinaryData sanitizeKey(const BinaryData &key)
 }
 
 void copyInPlace(const std::string &source,    const std::string &destination,
-                                       const std::function<bool(blkcnt_t)> &isTarget,
-                                       const std::function<void(int, int)> &addProgress)
+                                       unsigned int options,
+                                       ProgressBar& progress)
 {
        Ext4Tool ext4tool(source);
-       const blksize_t srcBlockSize = ext4tool.getBlockSize();
-       const blkcnt_t srcTotalBlockCount = ext4tool.getTotalBlockCount();
+       const uint32_t srcBlockSize = ext4tool.getBlockSize();
+       const uint32_t srcTotalBlockCount = ext4tool.getTotalBlockCount();
        char buf[srcBlockSize];
+       bool fastEncryption = true;
+
+       if (!(options & OPTION_INCLUDE_UNUSED_REGION)) {
+               INFO(SINK, "FastEncryption: Disabled");
+               fastEncryption = false;
+       } else {
+               INFO(SINK, "FastEncryption: Enabled");
+       }
 
        runtime::File src(source, O_RDONLY);
        runtime::File dst(destination, O_WRONLY);
 
        off_t pos = 0;
-       for (blkcnt_t n = 0; n < srcTotalBlockCount; n++, pos += srcBlockSize) {
-               if (!isTarget(n)) {
+       for (uint32_t n = 0; n < srcTotalBlockCount; n++, pos += srcBlockSize) {
+               if (!fastEncryption && !ext4tool.isUsedBlock(n)) {
                        continue;
                }
 
@@ -260,7 +268,7 @@ void copyInPlace(const std::string &source, const std::string &destination,
                src.read(buf, srcBlockSize);
                dst.write(buf, srcBlockSize);
 
-               addProgress(n, srcTotalBlockCount);
+               progress.update(n, srcTotalBlockCount);
        }
 }
 
@@ -327,21 +335,8 @@ void DMCryptEngine::encrypt(const BinaryData &key, unsigned int options)
        // should be encrypted here.
        auto cryptoBlkDev = createCryptoBlkDev(source, DM_DEFAULT_LABEL_NAME, sanitizeKey(key), DM_DEFAULT_CRYPTO_NAME);
 
-       std::function<bool(blkcnt_t)> isTarget;
-       if (!(options & OPTION_INCLUDE_UNUSED_REGION)) {
-               INFO(SINK, "FastEncryption: Disabled");
-               isTarget = std::bind(&Ext4Tool::isUsedBlock, &ext4Source, _1);
-       } else {
-               INFO(SINK, "FastEncryption: Enabled");
-               isTarget = [](unsigned int n) {
-                       return true;
-               };
-       }
-
        // We always do In-place encryption
-       copyInPlace(source, cryptoBlkDev, isTarget,
-                       std::bind((void(ProgressBar::*)(int, int, int))&ProgressBar::update,
-                                       &progress, _1, _2, 1));
+       copyInPlace(source, cryptoBlkDev, options, progress);
 
        // remove crypto type device mapper
        destroyCryptoBlkDev(DM_DEFAULT_LABEL_NAME);
@@ -368,21 +363,8 @@ void DMCryptEngine::decrypt(const BinaryData &key, unsigned int options)
                break;
        }
 
-       std::function<bool(blkcnt_t)> isTarget;
-       if (!(options & OPTION_INCLUDE_UNUSED_REGION)) {
-               INFO(SINK, "FastEncryption: Disabled");
-               isTarget = std::bind(&Ext4Tool::isUsedBlock, &ext4CryptoBlkDev, _1);
-       } else {
-               INFO(SINK, "FastEncryption: Enabled");
-               isTarget = [](unsigned int n) {
-                       return true;
-               };
-       }
-
        // We always do In-place decryption
-       copyInPlace(cryptoBlkDev, source, isTarget,
-                       std::bind((void(ProgressBar::*)(int, int, int))&ProgressBar::update,
-                                       &progress, _1, _2, 1));
+       copyInPlace(cryptoBlkDev, source, options, progress);
 
        // remove crypto type device mapper
        destroyCryptoBlkDev(DM_DEFAULT_LABEL_NAME);
index 61538c5..18f3ba9 100644 (file)
@@ -392,8 +392,10 @@ void EcryptfsEngine::encrypt(const BinaryData &key, unsigned int options)
                                                return true;
                                        },
                                        [&current, &totalSize, this](off_t size) {
+                                               if (current > std::numeric_limits<decltype(current)>::max() - size)
+                                                       throw runtime::Exception("Offset too big");
                                                current += size;
-                                               this->progress.update(current * 100 / totalSize);
+                                               this->progress.update(current, totalSize);
                                        });
                }
 
@@ -434,8 +436,10 @@ void EcryptfsEngine::decrypt(const BinaryData &key, unsigned int options)
                copyInPlace(tempMountpoint.getPath(), source,
                                        tempDir.getPath(), wasEncrypted,
                                        [&current, &totalSize, this](off_t size) {
+                                               if (current > std::numeric_limits<decltype(current)>::max() - size)
+                                                       throw runtime::Exception("Offset too big");
                                                current += size;
-                                               this->progress.update(current * 100 / totalSize);
+                                               this->progress.update(current, totalSize);
                                        });
                ecryptfsUmount(tempMountpoint.getPath());
 
index 6934340..b5ef2ea 100755 (executable)
@@ -352,8 +352,10 @@ void Ext4Engine::encrypt(const BinaryData& key, unsigned int options)
        off_t totalSize = getUsedSpace(source), current = 0;
        copyInPlace(destination, encrypted.getPath(),
                                [&current, &totalSize, this](off_t size) {
+                                       if (current > std::numeric_limits<decltype(current)>::max() - size)
+                                               throw runtime::Exception("Offset too big");
                                        current += size;
-                                       this->progress.update(current, totalSize, 1);
+                                       this->progress.update(current, totalSize);
                                });
 
        if (::mount(encrypted.getPath().c_str(), destination.c_str(), NULL, MS_BIND, 0) < 0) {
@@ -380,8 +382,10 @@ void Ext4Engine::decrypt(const BinaryData& key, unsigned int options)
        off_t totalSize = getUsedSpace(source), current = 0;
        copyInPlace(encrypted.getPath(), destination,
                                [&current, &totalSize, this](off_t size) {
+                                       if (current > std::numeric_limits<decltype(current)>::max() - size)
+                                               throw runtime::Exception("Offset too big");
                                        current += size;
-                                       this->progress.update(current, totalSize, 1);
+                                       this->progress.update(current, totalSize);
                                });
 
        encrypted.remove(true);
index ca508de..9bca4e1 100644 (file)
@@ -16,6 +16,8 @@
  */
 #include "erase-engine.h"
 
+#include <limits>
+
 #define ERASE_SIZE     4096
 
 namespace ode {
@@ -29,12 +31,15 @@ EraseEngine::~EraseEngine()
 {
 }
 
-void EraseEngine::discardBlock(unsigned long long offset, blksize_t size)
+void EraseEngine::discardBlock(uint64_t offset, uint32_t size)
 {
        char zero[ERASE_SIZE] = {};
        if (size > ERASE_SIZE) {
                throw runtime::Exception("[eraseBlock] : size is too big");
        }
+       if (offset > std::numeric_limits<off_t>::max()) {
+               throw runtime::Exception("[eraseBlock] : offset is too big");
+       }
 
        runtime::File device(target);
        device.open(O_WRONLY);
@@ -45,21 +50,21 @@ void EraseEngine::discardBlock(unsigned long long offset, blksize_t size)
 
 void EraseEngine::cleanDevice(const std::string &path)
 {
-       blkcnt_t totalBlockCount = 0;
-       blksize_t blockSize = 0;
-       unsigned long long offset = 0;
+       uint32_t totalBlockCount = 0;
+       uint32_t blockSize = 0;
+       uint64_t offset = 0;
        target = path;
 
        Ext4Tool ext4Tool(target);
-       totalBlockCount = (blkcnt_t)ext4Tool.getTotalBlockCount();
-       blockSize = (blksize_t)ext4Tool.getBlockSize();
+       totalBlockCount = ext4Tool.getTotalBlockCount();
+       blockSize = ext4Tool.getBlockSize();
 
-       for (blkcnt_t i = 0; i < totalBlockCount; i++) {
+       for (uint32_t i = 0; i < totalBlockCount; i++) {
                if (!ext4Tool.isUsedBlock(i)) {
-                       offset = (unsigned long long)i * (unsigned long long)blockSize;
+                       offset = static_cast<uint64_t>(i) * blockSize;
                        discardBlock(offset, blockSize);
                }
-               progressBar.update(i, totalBlockCount, 1);
+               progressBar.update(i, totalBlockCount);
        }
        progressBar.done();
 }
index 2ad61dd..d2f2d26 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <cstdint>
 #include <vconf.h>
 #include <klay/filesystem.h>
 #include <klay/exception.h>
@@ -44,7 +45,7 @@ public:
 
        void cleanDevice(const std::string &path);
 private:
-       void discardBlock(unsigned long long offset, blksize_t size);
+       void discardBlock(uint64_t offset, uint32_t size);
 private:
        ProgressBar progressBar;
        std::string target;
index 70cec3d..79bfcea 100644 (file)
@@ -41,10 +41,10 @@ void MMCEraseEngine::synchronization(void)
        return;
 }
 
-void MMCEraseEngine::discardBlock(unsigned long long offset, blksize_t size)
+void MMCEraseEngine::discardBlock(uint64_t offset, uint64_t size)
 {
        int descriptor = 0, ret = 0;
-       unsigned long long range[2] = {0, };
+       uint64_t range[2] = {0, };
 
        descriptor = ::open(target.c_str(), O_WRONLY);
        if (descriptor < 0) {
@@ -52,7 +52,7 @@ void MMCEraseEngine::discardBlock(unsigned long long offset, blksize_t size)
        }
 
        range[0] = offset;
-       range[1] = (unsigned long long)size;
+       range[1] = size;
 
        ret = ::ioctl(descriptor, BLKDISCARD, &range);
        ::close(descriptor);
@@ -63,21 +63,21 @@ void MMCEraseEngine::discardBlock(unsigned long long offset, blksize_t size)
 
 void MMCEraseEngine::cleanDevice(const std::string &path)
 {
-       blkcnt_t totalBlockCount = 0;
-       blksize_t blockSize = 0;
-       unsigned long long offset = 0;
+       uint32_t totalBlockCount = 0;
+       uint32_t blockSize = 0;
+       uint64_t offset = 0;
        target.append(path);
 
        Ext4Tool ext4Tool(target);
-       totalBlockCount = (blkcnt_t)ext4Tool.getTotalBlockCount();
-       blockSize = (blksize_t)ext4Tool.getBlockSize();
+       totalBlockCount = ext4Tool.getTotalBlockCount();
+       blockSize = ext4Tool.getBlockSize();
 
-       for (blkcnt_t i = 0; i < totalBlockCount; i++) {
+       for (uint32_t i = 0; i < totalBlockCount; i++) {
                if (!ext4Tool.isUsedBlock(i)) {
-                       offset = (unsigned long long)i * (unsigned long long)blockSize;
+                       offset = static_cast<uint64_t>(i) * blockSize;
                        discardBlock(offset, blockSize);
                }
-               progressBar.update(i, totalBlockCount, 1);
+               progressBar.update(i, totalBlockCount);
        }
        progressBar.done();
        synchronization();
index f6f969e..5cb2f25 100644 (file)
@@ -19,6 +19,7 @@
 #define __MMC_ERASE_ENGINE_H__
 
 #include <fstream>
+#include <cstdint>
 
 #include <fcntl.h>
 #include <unistd.h>
@@ -48,7 +49,7 @@ public:
        void cleanDevice(const std::string &target);
 private:
        void synchronization(void);
-       void discardBlock(unsigned long long offset, blksize_t size);
+       void discardBlock(uint64_t offset, uint64_t size);
 private:
        ProgressBar progressBar;
        std::string target;
index 2fc1ffe..47ffe49 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <string>
 #include <vector>
+#include <limits>
 
 #include <klay/filesystem.h>
 #include <klay/process.h>
@@ -37,7 +38,7 @@ namespace ode {
 
 namespace {
 
-unsigned int divCeilSafely(unsigned int a, unsigned int b)
+uint32_t divCeilSafely(uint32_t a, uint32_t b)
 {
        if (!a)
                return 0;
@@ -102,10 +103,11 @@ bool Ext4Tool::isExt(const std::string &src)
 
 void Ext4Tool::readInfo()
 {
-       unsigned int firstDataBlock = 0;
-       unsigned int blocksPerGroup = 0;
-       unsigned int clustersPerGroup = 0;
-       unsigned short descSize = 0;
+       // TODO this function should be rewritten
+       uint32_t firstDataBlock = 0;
+       uint32_t blocksPerGroup = 0;
+       uint32_t clustersPerGroup = 0;
+       uint16_t descSize = 0;
        runtime::File device(source);
 
        if (!device.exists())
@@ -115,95 +117,123 @@ void Ext4Tool::readInfo()
 
        // read totalBlockCount
        device.lseek(ODE_SUPERBLOCK_OFFSET +  4, SEEK_SET);
-       device.read(&totalBlockCount, 4);
+       device.read(&totalBlockCount, sizeof(totalBlockCount));
 
        // read firstDataBlock
        device.lseek(ODE_SUPERBLOCK_OFFSET + 20, SEEK_SET);
-       device.read(&firstDataBlock, 4);
+       device.read(&firstDataBlock, sizeof(firstDataBlock));
 
        // read blockSize
        device.lseek(ODE_SUPERBLOCK_OFFSET + 24, SEEK_SET);
-       device.read(&blockSize, 4);
+       device.read(&blockSize, sizeof(blockSize));
+       if ((std::numeric_limits<decltype(blockSize)>::max() >> blockSize) < ODE_EXT2_MIN_BLOCK_SIZE)
+               throw runtime::Exception("Block size too big"); // blockSize must be <= 21
        blockSize = (ODE_EXT2_MIN_BLOCK_SIZE << blockSize);
 
        // read blocksPerGroup
        device.lseek(ODE_SUPERBLOCK_OFFSET + 32, SEEK_SET);
-       device.read(&blocksPerGroup, 4);
+       device.read(&blocksPerGroup, sizeof(blocksPerGroup));
 
        // read clustersPerGroup
        device.lseek(ODE_SUPERBLOCK_OFFSET + 36, SEEK_SET);
-       device.read(&clustersPerGroup, 4);
+       device.read(&clustersPerGroup, sizeof(clustersPerGroup));
 
        // read descSize
        device.lseek(ODE_SUPERBLOCK_OFFSET + 0xFE, SEEK_SET);
-       device.read(&descSize, 2);
+       device.read(&descSize, sizeof(descSize));
        if (descSize < ODE_EXT2_MIN_DESC_SIZE) {
                descSize = ODE_EXT2_MIN_DESC_SIZE;
        }
 
-       unsigned int groupDescCount = divCeilSafely(totalBlockCount - firstDataBlock, blocksPerGroup);
-       int blockNbytes = clustersPerGroup / 8;
+       if (firstDataBlock >= totalBlockCount)
+               throw runtime::Exception("Invalid block info");
+       uint32_t groupDescCount = divCeilSafely(totalBlockCount - firstDataBlock, blocksPerGroup);
 
        // read group_desc
-       unsigned int descPerBlock = blockSize / descSize;
-       unsigned int descBlockCount = divCeilSafely(groupDescCount, descPerBlock);
+       uint32_t descPerBlock = blockSize / descSize;
+       uint32_t descBlockCount = divCeilSafely(groupDescCount, descPerBlock);
 
        // read first meta block
+       if (descBlockCount > std::numeric_limits<BinaryData::size_type>::max() / blockSize)
+               throw runtime::Exception("Size too big for BinaryData");
        BinaryData group_desc(descBlockCount * blockSize);
+       // firstDataBlock < totalBlockCount so no overflow is possible
        device.lseek((firstDataBlock + 1) * blockSize, SEEK_SET);
-       device.read(group_desc.data(), (descBlockCount * blockSize));
+       device.read(group_desc.data(), group_desc.size());
 
-       unsigned int cnt = blockNbytes << 3;
-       unsigned int blkItr = firstDataBlock;
+       uint32_t blkItr = firstDataBlock;
 
        // this structure just is used for easy type-casting.
        struct odeExtGroupDesc {
-               unsigned int    blockBitmap;    /* Blocks bitmap block */
+               uint32_t blockBitmap;   /* Blocks bitmap block */
                /* skip other member */
        };
 
        // read bitmap
        {
-               unsigned int start = firstDataBlock;
-               unsigned int real_end = blocksPerGroup * groupDescCount - 1 + start;
-               size_t size = (size_t) (((real_end - start) / 8) + 1);
+               uint32_t start = firstDataBlock;
+               uint32_t real_end = totalBlockCount - 1;
+
+               uint32_t size = (real_end - start) / 8 + 1;
                size = (size + 7) & ~3;
+               if (std::numeric_limits<size_t>::max() <= size)
+                       throw runtime::Exception("Bitmap size too big");
+
                bitmap.resize(size);
        }
 
-       for (unsigned int i = 0; i < groupDescCount; i++) {
-               unsigned int blk = (((struct odeExtGroupDesc *)(((unsigned char *)(group_desc.data())) + i * descSize))->blockBitmap);
+       if (groupDescCount >= group_desc.size() / descSize)
+               throw runtime::Exception("Group descriptors buffer too small");
+
+       if (blockSize > std::numeric_limits<size_t>::max())
+               throw runtime::Exception("Block size too big");
+
+       if (clustersPerGroup > std::numeric_limits<size_t>::max() - 7)
+               throw runtime::Exception("Too many clusters per group");
+
+       if (groupDescCount > (std::numeric_limits<decltype(blkItr)>::max() - blkItr) / clustersPerGroup + 1)
+               throw runtime::Exception("Block iterator may get too big");
+
+       if (((blkItr + clustersPerGroup * (groupDescCount - 1)) >> 3) + ((clustersPerGroup + 7) >> 3) > bitmap.size())
+               throw runtime::Exception("Bitmap size too small");
+
+       for (uint32_t i = 0; i < groupDescCount; i++) {
+               uint32_t blk = reinterpret_cast<odeExtGroupDesc*>(group_desc.data() + i * descSize)->blockBitmap;
 
                try {
                        BinaryData block_bitmap(blockSize);
+
+                       if (blk > std::numeric_limits<off_t>::max() / blockSize)
+                               throw runtime::Exception("Block bitmap index too big");
+
                        device.lseek(blk * blockSize, SEEK_SET);
                        device.read(block_bitmap.data(), blockSize);
 
-                       memcpy(bitmap.data() + (blkItr >> 3), block_bitmap.data(), (cnt + 7) >> 3);
+                       memcpy(bitmap.data() + (blkItr >> 3), block_bitmap.data(), (clustersPerGroup + 7) >> 3);
                } catch (runtime::Exception &e) {
                        WARN(SINK, "Block " + std::to_string(blk) + " is missing");
-                       memset(bitmap.data() + (blkItr >> 3), 0, (cnt + 7) >> 3);
+                       memset(bitmap.data() + (blkItr >> 3), 0, (clustersPerGroup + 7) >> 3);
                }
-               blkItr += cnt;
+               blkItr += clustersPerGroup;
        }
 
        device.close();
 }
 
-unsigned int Ext4Tool::getBlockSize()
+uint32_t Ext4Tool::getBlockSize()
 {
        return blockSize;
 }
 
-unsigned int Ext4Tool::getTotalBlockCount()
+uint32_t Ext4Tool::getTotalBlockCount()
 {
        return totalBlockCount;
 }
 
-bool Ext4Tool::isUsedBlock(unsigned int blockIndex)
+bool Ext4Tool::isUsedBlock(uint32_t blockIndex)
 {
        unsigned char *addr = (bitmap.data() + (blockIndex >> 3));
-       int mask = 1 << (blockIndex & 0x07);
+       unsigned char mask = 1 << (blockIndex & 0x07);
 
        if (mask & *addr)
                return true;
index 711d093..0b0d43c 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef __EXT4_TOOL_H__
 #define __EXT4_TOOL_H__
 
+#include <cstdint>
+
 #include <string>
 
 #include <klay/filesystem.h>
@@ -35,9 +37,9 @@ public:
        Ext4Tool &operator=(const Ext4Tool &) = delete;
        Ext4Tool &operator=(Ext4Tool &&) = delete;
 
-       unsigned int getBlockSize();
-       unsigned int getTotalBlockCount();
-       bool isUsedBlock(unsigned int blockIndex);
+       uint32_t getBlockSize();
+       uint32_t getTotalBlockCount();
+       bool isUsedBlock(uint32_t blockIndex);
        void forceCleanUp();
 
        static bool isExt(const std::string &src);
@@ -46,7 +48,7 @@ public:
 private:
        void readInfo();
        std::string source;
-       unsigned int blockSize, totalBlockCount;
+       uint32_t blockSize, totalBlockCount;
        BinaryData bitmap;
 };
 
index 09af99f..261a097 100644 (file)
@@ -206,7 +206,7 @@ ExternalEncryptionServer::ExternalEncryptionServer(ServerContext &srv,
 
        engine.reset(new EXTERNAL_ENGINE(
                EXTERNAL_PATH, EXTERNAL_PATH,
-               ProgressBar([](int v) {
+               ProgressBar([](unsigned v) {
                ::vconf_set_str(VCONFKEY_SDE_ENCRYPT_PROGRESS,
                                                std::to_string(v).c_str());
                })
index 3bc21b2..5e86b0c 100644 (file)
@@ -316,7 +316,7 @@ InternalEncryptionServer::InternalEncryptionServer(ServerContext& srv, KeyServer
 
        engine.reset(new INTERNAL_ENGINE(
                source, INTERNAL_PATH,
-               ProgressBar([](int v) {
+               ProgressBar([](unsigned v) {
                        ::vconf_set_str(VCONFKEY_ODE_ENCRYPT_PROGRESS,
                                                        std::to_string(v).c_str());
                })
index 6feef7c..cc9ea47 100644 (file)
@@ -28,7 +28,7 @@ ProgressBar::~ProgressBar()
 {
 }
 
-void ProgressBar::update(int value)
+void ProgressBar::update(unsigned value)
 {
        if (updateValue != value) {
                updateValue = value;
@@ -36,11 +36,6 @@ void ProgressBar::update(int value)
        }
 }
 
-void ProgressBar::update(int curCount, int totalCount, int unit)
-{
-       update(((curCount * 100) / totalCount) * unit);
-}
-
 void ProgressBar::done(void)
 {
        updateValue = 100;
index f2a7bb8..e28778a 100644 (file)
 #define __ODE_PROGRESS_BAR_H__
 
 #include <functional>
+#include <limits>
+#include <cassert>
 
 namespace ode {
 
 class ProgressBar {
 public:
-       typedef std::function<void(int)> UpdateFunc;
+       typedef std::function<void(unsigned)> UpdateFunc;
 
        ProgressBar() = delete;
-       ProgressBar(UpdateFunc const &updater);
+       explicit ProgressBar(UpdateFunc const &updater);
        ~ProgressBar();
 
-       void update(int value);
-       void update(int count, int totalCount, int unit);
+       void update(unsigned value);
+
+       template <typename T>
+       void update(T count, T totalCount);
+
        void done(void);
 
 private:
        UpdateFunc updater;
-       int updateValue;
+       unsigned updateValue;
 };
 
+
+template <typename T>
+void ProgressBar::update(T count, T totalCount)
+{
+       assert(count <= totalCount);
+       assert(totalCount > 0);
+
+       if (count > std::numeric_limits<T>::max() / 100)
+               update(count / (totalCount / 100));
+       else
+               update((count * 100) / totalCount);
+}
+
+
 } // namespace ode
 
 #endif //__ODE_PROGRESS_BAR_H__
index 025c2a2..7cbfab3 100644 (file)
@@ -55,7 +55,7 @@ SecureEraseServer::SecureEraseServer(ServerContext &srv) :
 {
        server.expose(this, PRIVILEGE_PLATFORM, (int)(SecureEraseServer::clean)(std::string));
 
-       engine.reset(new ERASE_ENGINE(ProgressBar([](int v) {
+       engine.reset(new ERASE_ENGINE(ProgressBar([](unsigned v) {
                        ::vconf_set_str(VCONFKEY_ODE_ERASE_PROGRESS, std::to_string(v).c_str());
                }))
        );
index 74c207f..051801f 100644 (file)
@@ -39,7 +39,7 @@ using namespace ode;
 
 namespace {
 
-ProgressBar progress([](int v) {});
+ProgressBar progress([](unsigned) {});
 
 }
 
index 6d13631..97005be 100644 (file)
@@ -25,7 +25,7 @@
 TESTCASE(EcryptfsGetPathTest)
 {
        try {
-               ode::ProgressBar progress([](int v) {});
+               ode::ProgressBar progress([](unsigned v) {});
                ode::EcryptfsEngine engine("/dev/mmcblkp0", "/opt/usr", progress);
                if (engine.getSource() != "/dev/mmcblkp0") {
                        throw runtime::Exception("Source doen't match");
index 97b3350..4c3d5a1 100755 (executable)
@@ -25,7 +25,7 @@
 TESTCASE(Ext4GetPathTest)
 {
        try {
-               ode::ProgressBar progress([](int v) {});
+               ode::ProgressBar progress([](unsigned v) {});
                ode::Ext4Engine engine("/dev/mmcblkp0", "/opt/usr", progress);
                if (engine.getSource() != "/dev/mmcblkp0") {
                        throw runtime::Exception("Source doen't match");