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