From e231a787b2a4708c64753c0254fb5a8c53af4240 Mon Sep 17 00:00:00 2001
From: Roman Tsisyk <roman@tsisyk.com>
Date: Wed, 1 Oct 2014 11:51:28 +0400
Subject: [PATCH] Review fixes for digest.base64 #367

---
 src/ffisyms.cc           |  2 ++
 src/lua/digest.lua       | 40 ++++++++++++++++------------------------
 test/box/digest.result   | 26 ++++++++++++++++++++++----
 test/box/digest.test.lua |  4 ++++
 third_party/base64.c     |  3 +++
 third_party/base64.h     |  2 +-
 6 files changed, 48 insertions(+), 29 deletions(-)

diff --git a/src/ffisyms.cc b/src/ffisyms.cc
index 6a6d8290d5..725dddb914 100644
--- a/src/ffisyms.cc
+++ b/src/ffisyms.cc
@@ -47,5 +47,7 @@ void *ffi_symbols[] = {
 	(void *) bsdsocket_local_resolve,
 	(void *) bsdsocket_nonblock,
 	(void *) base64_decode,
+	(void *) base64_encode,
+	(void *) base64_bufsize,
 	(void *) SHA1internal
 };
diff --git a/src/lua/digest.lua b/src/lua/digest.lua
index dd942480c2..3f5653be86 100644
--- a/src/lua/digest.lua
+++ b/src/lua/digest.lua
@@ -27,6 +27,7 @@ ffi.cdef[[
     extern crc32_func crc32_calc;
 
    /* base64 */
+   int base64_bufsize(int binsize);
    int base64_decode(const char *in_base64, int in_len, char *out_bin, int out_len);
    int base64_encode(const char *in_bin, int in_len, char *out_base64, int out_len);
 ]]
@@ -72,34 +73,25 @@ end
 
 local m = {
     base64_encode = function(bin)
-        if bin == nil then
-            error('Usage: base64.encode(str)')
-        else
-            -- note: need add check size of bin, bin might containe any binary data
-            if type(bin) == 'string' then
-                local blen = string.len(bin)
-                local slen = math.ceil(blen * 4 / 3) + 2
-                local so  = ffi.new('char[?]', slen)
-                local len = ffi.C.base64_encode(bin, blen, so, slen)
-                bin = ffi.string(so, len)
-            else
-                bin = ''
-            end
+        if type(bin) ~= 'string' then
+            error('Usage: digest.base64_encode(string)')
         end
-        return bin
+        local blen = #bin
+        local slen = ffi.C.base64_bufsize(blen)
+        local str  = ffi.new('char[?]', slen)
+        local len = ffi.C.base64_encode(bin, blen, str, slen)
+        return ffi.string(str, len)
     end,
 
-    base64_decode = function(data)
-        if type(data) ~= 'string' then
-            data = ''
-        else
-            local slen = string.len(data)
-            local blen = math.ceil(slen * 3 / 4)
-            local bo  = ffi.new('char[?]', blen)
-            local len = ffi.C.base64_decode(data, slen, bo, blen)
-            data = ffi.string(bo, len)
+    base64_decode = function(str)
+        if type(str) ~= 'string' then
+            error('Usage: digest.base64_decode(string)')
         end
-        return data
+        local slen = #str
+        local blen = math.ceil(slen * 3 / 4)
+        local bin  = ffi.new('char[?]', blen)
+        local len = ffi.C.base64_decode(str, slen, bin, blen)
+        return ffi.string(bin, len)
     end,
 
     crc32 = function(str)
diff --git a/test/box/digest.result b/test/box/digest.result
index 21588a9f96..0113ed92b6 100644
--- a/test/box/digest.result
+++ b/test/box/digest.result
@@ -173,21 +173,39 @@ digest.base64_decode('MTEgMDAgMTEgMDAgYWJjZGVmIEFCQ0RFRiAwMCAxMSAwMCAxMQ==')
 ---
 - 11 00 11 00 abcdef ABCDEF 00 11 00 11
 ...
+s = string.rep('a', 54 * 2) -- two lines in base64
+---
+...
+b = digest.base64_encode(s)
+---
+...
+b
+---
+- 'YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh
+
+  YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh
+
+'
+...
+digest.base64_decode(b) == s
+---
+- true
+...
 digest.base64_decode(nil)
 ---
-- 
+- error: 'builtin/digest.lua:88: Usage: digest.base64_decode(string)'
 ...
 digest.base64_encode(nil)
 ---
-- error: 'builtin/digest.lua:76: Usage: base64.encode(str)'
+- error: 'builtin/digest.lua:77: Usage: digest.base64_encode(string)'
 ...
 digest.base64_encode(123)
 ---
-- 
+- error: 'builtin/digest.lua:77: Usage: digest.base64_encode(string)'
 ...
 digest.base64_decode(123)
 ---
-- 
+- error: 'builtin/digest.lua:88: Usage: digest.base64_decode(string)'
 ...
 digest = nil
 ---
diff --git a/test/box/digest.test.lua b/test/box/digest.test.lua
index f988abc98b..6475bf6b65 100644
--- a/test/box/digest.test.lua
+++ b/test/box/digest.test.lua
@@ -50,6 +50,10 @@ digest.base64_encode('asdfl asdf adfa zxc vzxcvz llll')
 digest.base64_decode('YXNkZmwgYXNkZiBhZGZhIHp4YyB2enhjdnogbGxsbA==')
 digest.base64_encode('11 00 11 00 abcdef ABCDEF 00 11 00 11')
 digest.base64_decode('MTEgMDAgMTEgMDAgYWJjZGVmIEFCQ0RFRiAwMCAxMSAwMCAxMQ==')
+s = string.rep('a', 54 * 2) -- two lines in base64
+b = digest.base64_encode(s)
+b
+digest.base64_decode(b) == s
 digest.base64_decode(nil)
 digest.base64_encode(nil)
 digest.base64_encode(123)
diff --git a/third_party/base64.c b/third_party/base64.c
index e2fb9785c4..49a4f2492d 100644
--- a/third_party/base64.c
+++ b/third_party/base64.c
@@ -35,6 +35,9 @@
 
 /* {{{ encode */
 
+extern inline int
+base64_bufsize(int binsize);
+
 enum base64_encodestep { step_A, step_B, step_C };
 
 struct base64_encodestate {
diff --git a/third_party/base64.h b/third_party/base64.h
index d590820ddb..a52a5e91f7 100644
--- a/third_party/base64.h
+++ b/third_party/base64.h
@@ -39,7 +39,7 @@ extern "C" {
 
 #define BASE64_CHARS_PER_LINE 72
 
-static inline int
+inline int
 base64_bufsize(int binsize)
 {
 	int datasize = binsize * 4/3 + 4;
-- 
GitLab