forked from Mirrors/wine-wine
inetcomm: Added support for decoding quoted-printable data.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>oldstable
parent
07af9d0db3
commit
0672bfa216
|
@ -1614,6 +1614,90 @@ static HRESULT decode_base64(IStream *input, IStream **ret_stream)
|
||||||
return S_OK;
|
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(
|
static HRESULT WINAPI MimeBody_GetData(
|
||||||
IMimeBody* iface,
|
IMimeBody* iface,
|
||||||
ENCODINGTYPE ietEncoding,
|
ENCODINGTYPE ietEncoding,
|
||||||
|
@ -1628,12 +1712,19 @@ static HRESULT WINAPI MimeBody_GetData(
|
||||||
if(This->encoding != ietEncoding) {
|
if(This->encoding != ietEncoding) {
|
||||||
switch(This->encoding) {
|
switch(This->encoding) {
|
||||||
case IET_BASE64:
|
case IET_BASE64:
|
||||||
if(ietEncoding != IET_BINARY)
|
hres = decode_base64(This->data, ppStream);
|
||||||
FIXME("Encofing %d is not supported.\n", ietEncoding);
|
break;
|
||||||
return decode_base64(This->data, ppStream);
|
case IET_QP:
|
||||||
|
hres = decode_qp(This->data, ppStream);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
FIXME("Decoding %d is not supported.\n", This->encoding);
|
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;
|
start.QuadPart = 0;
|
||||||
|
|
|
@ -556,6 +556,20 @@ static void test_SetData(void)
|
||||||
test_stream_read(stream, S_OK, " \t\r", 3);
|
test_stream_read(stream, S_OK, " \t\r", 3);
|
||||||
IStream_Release(stream);
|
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);
|
IMimeBody_Release(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue