inetcomm: Copy RFC822 headers into a memory block for later parsing.
This commit is contained in:
parent
c2f0697763
commit
98dfca50bb
|
@ -2,6 +2,7 @@
|
|||
* MIME OLE Interfaces
|
||||
*
|
||||
* Copyright 2006 Robert Shearman for CodeWeavers
|
||||
* Copyright 2007 Huw Davies for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -49,6 +50,86 @@ static inline MimeBody *impl_from_IMimeBody( IMimeBody *iface )
|
|||
return (MimeBody *)((char*)iface - FIELD_OFFSET(MimeBody, lpVtbl));
|
||||
}
|
||||
|
||||
#define PARSER_BUF_SIZE 1024
|
||||
|
||||
/*****************************************************
|
||||
* copy_headers_to_buf [internal]
|
||||
*
|
||||
* Copies the headers into a '\0' terminated memory block and leave
|
||||
* the stream's current position set to after the blank line.
|
||||
*/
|
||||
static HRESULT copy_headers_to_buf(IStream *stm, char **ptr)
|
||||
{
|
||||
char *buf = NULL;
|
||||
DWORD size = PARSER_BUF_SIZE, offset = 0, last_end = 0;
|
||||
HRESULT hr;
|
||||
int done = 0;
|
||||
|
||||
*ptr = NULL;
|
||||
|
||||
do
|
||||
{
|
||||
char *end;
|
||||
DWORD read;
|
||||
|
||||
if(!buf)
|
||||
buf = HeapAlloc(GetProcessHeap(), 0, size + 1);
|
||||
else
|
||||
{
|
||||
size *= 2;
|
||||
buf = HeapReAlloc(GetProcessHeap(), 0, buf, size + 1);
|
||||
}
|
||||
if(!buf)
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hr = IStream_Read(stm, buf + offset, size - offset, &read);
|
||||
if(FAILED(hr)) goto fail;
|
||||
|
||||
offset += read;
|
||||
buf[offset] = '\0';
|
||||
|
||||
if(read == 0) done = 1;
|
||||
|
||||
while(!done && (end = strstr(buf + last_end, "\r\n")))
|
||||
{
|
||||
DWORD new_end = end - buf + 2;
|
||||
if(new_end - last_end == 2)
|
||||
{
|
||||
LARGE_INTEGER off;
|
||||
off.QuadPart = new_end;
|
||||
IStream_Seek(stm, off, STREAM_SEEK_SET, NULL);
|
||||
buf[new_end] = '\0';
|
||||
done = 1;
|
||||
}
|
||||
else
|
||||
last_end = new_end;
|
||||
}
|
||||
} while(!done);
|
||||
|
||||
*ptr = buf;
|
||||
return S_OK;
|
||||
|
||||
fail:
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT parse_headers(MimeBody *body, IStream *stm)
|
||||
{
|
||||
char *header_buf;
|
||||
HRESULT hr;
|
||||
|
||||
hr = copy_headers_to_buf(stm, &header_buf);
|
||||
if(FAILED(hr)) return hr;
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, header_buf);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI MimeBody_QueryInterface(IMimeBody* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject)
|
||||
|
@ -119,8 +200,9 @@ static HRESULT WINAPI MimeBody_Load(
|
|||
IMimeBody* iface,
|
||||
LPSTREAM pStm)
|
||||
{
|
||||
FIXME("(%p)->(%p): stub\n", iface, pStm);
|
||||
return E_NOTIMPL;
|
||||
MimeBody *This = impl_from_IMimeBody(iface);
|
||||
TRACE("(%p)->(%p)\n", iface, pStm);
|
||||
return parse_headers(This, pStm);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MimeBody_Save(
|
||||
|
@ -143,8 +225,8 @@ static HRESULT WINAPI MimeBody_GetSizeMax(
|
|||
static HRESULT WINAPI MimeBody_InitNew(
|
||||
IMimeBody* iface)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
TRACE("%p->()\n", iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MimeBody_GetPropInfo(
|
||||
|
|
|
@ -32,6 +32,32 @@
|
|||
|
||||
#include "wine/test.h"
|
||||
|
||||
static char msg1[] =
|
||||
"MIME-Version: 1.0\r\n"
|
||||
"Content-Type: multipart/mixed;\r\n"
|
||||
" boundary=\"------------1.5.0.6\";\r\n"
|
||||
" stuff=\"du;nno\"\r\n"
|
||||
"foo: bar\r\n"
|
||||
"From: Huw Davies <huw@codeweavers.com>\r\n"
|
||||
"From: Me <xxx@codeweavers.com>\r\n"
|
||||
"To: wine-patches <wine-patches@winehq.org>\r\n"
|
||||
"Cc: Huw Davies <huw@codeweavers.com>,\r\n"
|
||||
" \"Fred Bloggs\" <fred@bloggs.com>\r\n"
|
||||
"foo: baz\r\n"
|
||||
"bar: fum\r\n"
|
||||
"\r\n"
|
||||
"This is a multi-part message in MIME format.\r\n"
|
||||
"--------------1.5.0.6\r\n"
|
||||
"Content-Type: text/plain; format=fixed; charset=UTF-8\r\n"
|
||||
"Content-Transfer-Encoding: 8bit\r\n"
|
||||
"\r\n"
|
||||
"Stuff\r\n"
|
||||
"--------------1.5.0.6\r\n"
|
||||
"Content-Type: text/plain; charset=\"us-ascii\"\r\n"
|
||||
"Content-Transfer-Encoding: 7bit\r\n"
|
||||
"\r\n"
|
||||
"More stuff\r\n"
|
||||
"--------------1.5.0.6--\r\n";
|
||||
|
||||
static void test_CreateVirtualStream(void)
|
||||
{
|
||||
|
@ -60,6 +86,9 @@ static void test_CreateBody(void)
|
|||
HRESULT hr;
|
||||
IMimeBody *body;
|
||||
HBODY handle = (void *)0xdeadbeef;
|
||||
IStream *in;
|
||||
LARGE_INTEGER off;
|
||||
ULARGE_INTEGER pos;
|
||||
|
||||
hr = CoCreateInstance(&CLSID_IMimeBody, NULL, CLSCTX_INPROC_SERVER, &IID_IMimeBody, (void**)&body);
|
||||
ok(hr == S_OK, "ret %08x\n", hr);
|
||||
|
@ -68,6 +97,22 @@ static void test_CreateBody(void)
|
|||
ok(hr == MIME_E_NO_DATA, "ret %08x\n", hr);
|
||||
ok(handle == NULL, "handle %p\n", handle);
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &in);
|
||||
ok(hr == S_OK, "ret %08x\n", hr);
|
||||
IStream_Write(in, msg1, sizeof(msg1) - 1, NULL);
|
||||
off.QuadPart = 0;
|
||||
IStream_Seek(in, off, STREAM_SEEK_SET, NULL);
|
||||
|
||||
/* Need to call InitNew before Load otherwise Load crashes with native inetcomm */
|
||||
hr = IMimeBody_InitNew(body);
|
||||
ok(hr == S_OK, "ret %08x\n", hr);
|
||||
|
||||
hr = IMimeBody_Load(body, in);
|
||||
ok(hr == S_OK, "ret %08x\n", hr);
|
||||
off.QuadPart = 0;
|
||||
IStream_Seek(in, off, STREAM_SEEK_CUR, &pos);
|
||||
ok(pos.LowPart == 328, "pos %u\n", pos.LowPart);
|
||||
|
||||
IMimeBody_Release(body);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue