]> git.stg.codes - stg.git/commitdiff
Fixed BFStream work with large strings, allowed null put on last.
authorMaxim Mamontov <faust.madf@gmail.com>
Mon, 22 Sep 2014 20:25:10 +0000 (23:25 +0300)
committerMaxim Mamontov <faust.madf@gmail.com>
Mon, 22 Sep 2014 20:25:10 +0000 (23:25 +0300)
stglibs/crypto.lib/bfstream.cpp
tests/test_bfstream.cpp

index 9c3f678edeca136ee754daa009d3b7f0f7a84669..3325bd1a2c8052862295f3902f90e619f6cd0aa9 100644 (file)
@@ -33,7 +33,7 @@ class COMMON
         void Put(const void * data, size_t size, bool last)
         {
         size_t dataSize = m_ptr - m_buffer;
         void Put(const void * data, size_t size, bool last)
         {
         size_t dataSize = m_ptr - m_buffer;
-        if (dataSize + size > sizeof(m_buffer))
+        while (dataSize + size > sizeof(m_buffer))
             {
             memcpy(m_ptr, data, sizeof(m_buffer) - dataSize); // Fill buffer
             size -= sizeof(m_buffer) - dataSize; // Adjust size
             {
             memcpy(m_ptr, data, sizeof(m_buffer) - dataSize); // Fill buffer
             size -= sizeof(m_buffer) - dataSize; // Adjust size
@@ -41,6 +41,7 @@ class COMMON
             m_proc(m_buffer, m_buffer, sizeof(m_buffer), &m_ctx); // Process
             m_ok = m_ok && m_callback(m_buffer, sizeof(m_buffer), m_data); // Consume
             m_ptr = m_buffer;
             m_proc(m_buffer, m_buffer, sizeof(m_buffer), &m_ctx); // Process
             m_ok = m_ok && m_callback(m_buffer, sizeof(m_buffer), m_data); // Consume
             m_ptr = m_buffer;
+            dataSize = 0;
             }
         if (!m_ok)
             return;
             }
         if (!m_ok)
             return;
@@ -69,7 +70,7 @@ class COMMON
             dataSize += 8;
             remainder = 0;
             }
             dataSize += 8;
             remainder = 0;
             }
-        if (dataSize == 0)
+        if (!last && dataSize == 0) // Allow to call callback with 0 data on last call.
             return;
         m_proc(m_buffer, m_buffer, dataSize, &m_ctx);
         m_ok = m_ok && m_callback(m_buffer, dataSize, m_data);
             return;
         m_proc(m_buffer, m_buffer, dataSize, &m_ctx);
         m_ok = m_ok && m_callback(m_buffer, dataSize, m_data);
index f80dc8d856cd326c1fb2e086c43f54d6cf191ce4..892d575973286c2e54914a4dae3a1ddd7a4e465e 100644 (file)
@@ -1,5 +1,7 @@
 #include "tut/tut.hpp"
 
 #include "tut/tut.hpp"
 
+#include "longstring.h"
+
 #include "stg/bfstream.h"
 #include "stg/os_int.h"
 
 #include "stg/bfstream.h"
 #include "stg/os_int.h"
 
@@ -22,6 +24,7 @@ class TRACKER
             {
             m_lastBlock = new char[size];
             memcpy(m_lastBlock,  block, size);
             {
             m_lastBlock = new char[size];
             memcpy(m_lastBlock,  block, size);
+            m_result.append(m_lastBlock, size);
             }
         else
             m_lastBlock = NULL;
             }
         else
             m_lastBlock = NULL;
@@ -33,12 +36,63 @@ class TRACKER
         size_t CallCount() const { return m_callCount; }
         const void * LastBlock() const { return m_lastBlock; }
 
         size_t CallCount() const { return m_callCount; }
         const void * LastBlock() const { return m_lastBlock; }
 
+        const std::string& Result() const { return m_result; }
+
     private:
         size_t m_lastSize;
         size_t m_callCount;
         char * m_lastBlock;
     private:
         size_t m_lastSize;
         size_t m_callCount;
         char * m_lastBlock;
+
+        std::string m_result;
+};
+
+bool DecryptCallback(const void * block, size_t size, void * data);
+
+class Decryptor
+{
+    public:
+        Decryptor(const std::string & key)
+            : m_stream(key, DecryptCallback, this)
+        {}
+
+        bool Call(const void * block, size_t size)
+        {
+            m_stream.Put(block, size);
+            return true;
+        }
+
+        bool Put(const void * block, size_t size)
+        {
+            const char * data = static_cast<const char *>(block);
+            size = strnlen(data, size);
+            m_result.append(data, size);
+            return true;
+        }
+
+        void Flush()
+        {
+            m_stream.Put(NULL, 0);
+        }
+
+        const std::string & Result() const { return m_result; }
+
+    private:
+        STG::DECRYPT_STREAM m_stream;
+        std::string m_result;
 };
 
 };
 
+bool EncryptCallback(const void * block, size_t size, void * data)
+{
+Decryptor & decryptor = *static_cast<Decryptor *>(data);
+return decryptor.Call(block, size);
+}
+
+bool DecryptCallback(const void * block, size_t size, void * data)
+{
+Decryptor & decryptor = *static_cast<Decryptor *>(data);
+return decryptor.Put(block, size);
+}
+
 bool Callback(const void * block, size_t size, void * data)
 {
 TRACKER & tracker = *static_cast<TRACKER *>(data);
 bool Callback(const void * block, size_t size, void * data)
 {
 TRACKER & tracker = *static_cast<TRACKER *>(data);
@@ -139,4 +193,47 @@ namespace tut
         ensure_equals("Decrypt(Encrypt(source)) == source", std::string(buffer), source);
     }
 
         ensure_equals("Decrypt(Encrypt(source)) == source", std::string(buffer), source);
     }
 
+    template<>
+    template<>
+    void testobject::test<4>()
+    {
+        set_test_name("Check bfstream very long string processing");
+
+        Decryptor decryptor("pr7Hhen");
+        STG::ENCRYPT_STREAM estream("pr7Hhen", EncryptCallback, &decryptor);
+        //char buffer[source.length() + 9];
+        //memset(buffer, 0, sizeof(buffer));
+
+        estream.Put(longString.c_str(), longString.length() + 1, true);
+        //ensure("Encryption long string LastSize()", tracker.LastSize() >= source.length() + 1);
+        //ensure("Encryption long string LastBlock() != NULL", tracker.LastBlock() != NULL);
+        //memcpy(buffer, tracker.LastBlock(), std::min(tracker.LastSize(), sizeof(buffer)));
+
+        //dstream.Put(buffer, sizeof(buffer), true);
+        //ensure("Decryption long string LastSize() decryption", tracker.LastSize() >= sizeof(buffer));
+        //ensure("Decryption long string LastBlock() != NULL", tracker.LastBlock() != NULL);
+        //memcpy(buffer, tracker.LastBlock(), std::min(tracker.LastSize(), sizeof(buffer)));
+
+        ensure_equals("Decrypt(Encrypt(source)) == source", decryptor.Result(), longString);
+    }
+
+    template<>
+    template<>
+    void testobject::test<5>()
+    {
+        set_test_name("Check bfstream mechanics");
+
+        TRACKER tracker;
+        STG::ENCRYPT_STREAM stream("pr7Hhen", Callback, &tracker);
+        ensure_equals("CallCount() == 0 after construction", tracker.CallCount(), 0);
+
+        uint32_t block[2] = {0x12345678, 0x87654321};
+        stream.Put(&block[0], sizeof(block[0]));
+        ensure_equals("CallCount() == 0 after first put", tracker.CallCount(), 0);
+        stream.Put(&block[1], sizeof(block[1]));
+        ensure_equals("CallCount() == 1 after second put", tracker.CallCount(), 1);
+        stream.Put(&block[0], 0, true); // Check last callback
+        ensure_equals("CallCount() == 2 after third (null) put", tracker.CallCount(), 2);
+    }
+
 }
 }