Jacek Caban : inetcomm: Added support for decoding base64 in IMimeBody:: GetData.

Alexandre Julliard julliard at winehq.org
Mon Jan 30 15:39:16 CST 2017


Module: wine
Branch: master
Commit: 915acd68de3531348d36bd31a02413b122554221
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=915acd68de3531348d36bd31a02413b122554221

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Jan 27 16:01:07 2017 +0100

inetcomm: Added support for decoding base64 in IMimeBody::GetData.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/inetcomm/mimeole.c       | 95 ++++++++++++++++++++++++++++++++++++++++++-
 dlls/inetcomm/tests/mimeole.c | 22 ++++++++++
 2 files changed, 116 insertions(+), 1 deletion(-)

diff --git a/dlls/inetcomm/mimeole.c b/dlls/inetcomm/mimeole.c
index 0f0da61..90a5dd4 100644
--- a/dlls/inetcomm/mimeole.c
+++ b/dlls/inetcomm/mimeole.c
@@ -1515,6 +1515,88 @@ static HRESULT WINAPI MimeBody_GetDataHere(
     return E_NOTIMPL;
 }
 
+static const signed char base64_decode_table[] =
+{
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00 */
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10 */
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20 */
+    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30 */
+    -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, /* 0x40 */
+    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50 */
+    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60 */
+    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1  /* 0x70 */
+};
+
+static HRESULT decode_base64(IStream *input, IStream **ret_stream)
+{
+    const unsigned char *ptr, *end;
+    unsigned char buf[1024];
+    LARGE_INTEGER pos;
+    unsigned char *ret;
+    unsigned char in[4];
+    IStream *output;
+    DWORD size;
+    int n = 0;
+    HRESULT hres;
+
+    pos.QuadPart = 0;
+    hres = IStream_Seek(input, pos, STREAM_SEEK_SET, NULL);
+    if(FAILED(hres))
+        return hres;
+
+    hres = CreateStreamOnHGlobal(NULL, TRUE, &output);
+    if(FAILED(hres))
+        return hres;
+
+    while(1) {
+        hres = IStream_Read(input, buf, sizeof(buf), &size);
+        if(FAILED(hres) || !size)
+            break;
+
+        ptr = ret = buf;
+        end = buf + size;
+
+        while(1) {
+            /* skip invalid chars */
+            while(ptr < end &&
+                  (*ptr >= sizeof(base64_decode_table)/sizeof(*base64_decode_table)
+                   || base64_decode_table[*ptr] == -1))
+                ptr++;
+            if(ptr == end)
+                break;
+
+            in[n++] = base64_decode_table[*ptr++];
+            switch(n) {
+            case 2:
+                *ret++ = in[0] << 2 | in[1] >> 4;
+                continue;
+            case 3:
+                *ret++ = in[1] << 4 | in[2] >> 2;
+                continue;
+            case 4:
+                *ret++ = ((in[2] << 6) & 0xc0) | in[3];
+                n = 0;
+            }
+        }
+
+        if(ret > buf) {
+            hres = IStream_Write(output, buf, ret - buf, NULL);
+            if(FAILED(hres))
+                break;
+        }
+    }
+
+    if(SUCCEEDED(hres))
+        hres = IStream_Seek(output, pos, STREAM_SEEK_SET, NULL);
+    if(FAILED(hres)) {
+        IStream_Release(output);
+        return hres;
+    }
+
+    *ret_stream = output;
+    return S_OK;
+}
+
 static HRESULT WINAPI MimeBody_GetData(
                               IMimeBody* iface,
                               ENCODINGTYPE ietEncoding,
@@ -1524,7 +1606,18 @@ static HRESULT WINAPI MimeBody_GetData(
     ULARGE_INTEGER start, size;
     HRESULT hres;
 
-    FIXME("(%p)->(%d, %p). Ignoring encoding type.\n", This, ietEncoding, ppStream);
+    TRACE("(%p)->(%d %p)\n", This, ietEncoding, ppStream);
+
+    if(This->encoding != ietEncoding) {
+        switch(This->encoding) {
+        case IET_BASE64:
+            if(ietEncoding != IET_BINARY)
+                FIXME("Encofing %d is not supported.\n", ietEncoding);
+            return decode_base64(This->data, ppStream);
+        default:
+            FIXME("Decoding %d is not supported.\n", This->encoding);
+        }
+    }
 
     start.QuadPart = 0;
     hres = get_stream_size(This->data, &size);
diff --git a/dlls/inetcomm/tests/mimeole.c b/dlls/inetcomm/tests/mimeole.c
index 5d7bb9a..0765396 100644
--- a/dlls/inetcomm/tests/mimeole.c
+++ b/dlls/inetcomm/tests/mimeole.c
@@ -494,6 +494,28 @@ static void test_SetData(void)
     IStream_Release(stream);
     IStream_Release(stream2);
     IStream_Release(&test_stream->IStream_iface);
+
+    stream = create_stream_from_string(" \t\r\n|}~YWJj ZGV|}~mZw== \t"); /* "abcdefg" in base64 obscured by invalid chars */
+    hr = IMimeBody_SetData(body, IET_BASE64, "text", "plain", &IID_IStream, stream);
+    IStream_Release(stream);
+    ok(hr == S_OK, "SetData failed: %08x\n", hr);
+
+    test_current_encoding(body, IET_BASE64);
+
+    hr = IMimeBody_GetData(body, IET_BINARY, &stream);
+    ok(hr == S_OK, "GetData failed %08x\n", hr);
+
+    test_stream_read(stream, S_OK, "abc", 3);
+    test_stream_read(stream, S_OK, "defg", -1);
+
+    IStream_Release(stream);
+
+    hr = IMimeBody_GetData(body, IET_BASE64, &stream);
+    ok(hr == S_OK, "GetData failed %08x\n", hr);
+
+    test_stream_read(stream, S_OK, " \t\r", 3);
+    IStream_Release(stream);
+
     IMimeBody_Release(body);
 }
 




More information about the wine-cvs mailing list