Jacek Caban : inetcomm: Added support for decoding quoted-printable data.

Alexandre Julliard julliard at winehq.org
Wed Feb 1 15:26:06 CST 2017


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Feb  1 11:23:39 2017 +0100

inetcomm: Added support for decoding quoted-printable data.

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

---

 dlls/inetcomm/mimeole.c       | 97 +++++++++++++++++++++++++++++++++++++++++--
 dlls/inetcomm/tests/mimeole.c | 14 +++++++
 2 files changed, 108 insertions(+), 3 deletions(-)

diff --git a/dlls/inetcomm/mimeole.c b/dlls/inetcomm/mimeole.c
index c55be72..0ed7cef 100644
--- a/dlls/inetcomm/mimeole.c
+++ b/dlls/inetcomm/mimeole.c
@@ -1614,6 +1614,90 @@ static HRESULT decode_base64(IStream *input, IStream **ret_stream)
     return S_OK;
 }
 
+static int hex_digit(char c)
+{
+    if('0' <= c && c <= '9')
+        return c - '0';
+    if('A' <= c && c <= 'F')
+        return c - 'A' + 10;
+    if('a' <= c && c <= 'f')
+        return c - 'a' + 10;
+    return -1;
+}
+
+static HRESULT decode_qp(IStream *input, IStream **ret_stream)
+{
+    const unsigned char *ptr, *end;
+    unsigned char *ret, prev = 0;
+    unsigned char buf[1024];
+    LARGE_INTEGER pos;
+    IStream *output;
+    DWORD size;
+    int n = -1;
+    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(ptr < end) {
+            unsigned char byte = *ptr++;
+
+            switch(n) {
+            case -1:
+                if(byte == '=')
+                    n = 0;
+                else
+                    *ret++ = byte;
+                continue;
+            case 0:
+                prev = byte;
+                n = 1;
+                continue;
+            case 1:
+                if(prev != '\r' || byte != '\n') {
+                    int h1 = hex_digit(prev), h2 = hex_digit(byte);
+                    if(h1 != -1 && h2 != -1)
+                        *ret++ = (h1 << 4) | h2;
+                    else
+                        *ret++ = '=';
+                }
+                n = -1;
+                continue;
+            }
+        }
+
+        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,
@@ -1628,12 +1712,19 @@ static HRESULT WINAPI MimeBody_GetData(
     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);
+            hres = decode_base64(This->data, ppStream);
+            break;
+        case IET_QP:
+            hres = decode_qp(This->data, ppStream);
+            break;
         default:
             FIXME("Decoding %d is not supported.\n", This->encoding);
+            hres = S_FALSE;
         }
+        if(ietEncoding != IET_BINARY)
+            FIXME("Encoding %d is not supported.\n", ietEncoding);
+        if(hres != S_FALSE)
+            return hres;
     }
 
     start.QuadPart = 0;
diff --git a/dlls/inetcomm/tests/mimeole.c b/dlls/inetcomm/tests/mimeole.c
index c680938..fbee6e1 100644
--- a/dlls/inetcomm/tests/mimeole.c
+++ b/dlls/inetcomm/tests/mimeole.c
@@ -556,6 +556,20 @@ static void test_SetData(void)
     test_stream_read(stream, S_OK, " \t\r", 3);
     IStream_Release(stream);
 
+    stream = create_stream_from_string(" =3d=3D\"one\" \t=\r\ntw=  o=\nx3\n=34\r\n5");
+    hr = IMimeBody_SetData(body, IET_QP, "text", "plain", &IID_IStream, stream);
+    IStream_Release(stream);
+    ok(hr == S_OK, "SetData failed: %08x\n", hr);
+
+    test_current_encoding(body, IET_QP);
+
+    hr = IMimeBody_GetData(body, IET_BINARY, &stream);
+    ok(hr == S_OK, "GetData failed %08x\n", hr);
+
+    test_stream_read(stream, S_OK, " ==\"one\" \ttw=o=3\n4\r\n5", -1);
+
+    IStream_Release(stream);
+
     IMimeBody_Release(body);
 }
 




More information about the wine-cvs mailing list