Re: Resend: RICHED20: fall back to simple test
Hi Phil, This patch broke Internet Explorer 6 installation. The installer gets into an infinite loop reading the License text for the first dialog. Mike Phil Krylov wrote:
Hi,
this version of patch is made against current CVS.
ChangeLog:
Make RTF reader fall back to simple text if a correct RTF header is not detected. This should fix some installers.
Patch:
Index: dlls/riched20/editor.c =================================================================== RCS file: /home/wine/wine/dlls/riched20/editor.c,v retrieving revision 1.22 diff -p -u -r1.22 editor.c --- dlls/riched20/editor.c 11 Apr 2005 14:22:21 -0000 1.22 +++ dlls/riched20/editor.c 13 Apr 2005 07:13:21 -0000 @@ -233,36 +233,40 @@ ME_TextBuffer *ME_MakeText() { return buf; }
-#define STREAMIN_BUFFER_SIZE 4096 /* M$ compatibility */
-static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream, ME_Style *style) +static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, ME_InStream *stream, ME_Style *style) { - BYTE buffer[STREAMIN_BUFFER_SIZE+1]; WCHAR wszText[STREAMIN_BUFFER_SIZE+1]; + WCHAR *pText;
TRACE("%08lx %p\n", dwFormat, stream); - stream->dwError = 0;
do { - long nDataSize = 0, nWideChars = 0; - stream->dwError = stream->pfnCallback(stream->dwCookie, - (dwFormat & SF_UNICODE ? (BYTE *)wszText : buffer), - STREAMIN_BUFFER_SIZE, &nDataSize); - - if (stream->dwError) - break; - if (!nDataSize) - break; + long nWideChars = 0; + + if (!stream->dwSize) + { + ME_StreamInFill(stream); + if (stream->editstream->dwError) + break; + if (!stream->dwSize) + break; + }
if (!(dwFormat & SF_UNICODE)) { /* FIXME? this is doomed to fail on true MBCS like UTF-8, luckily they're unlikely to be used as CP_ACP */ - nWideChars = MultiByteToWideChar(CP_ACP, 0, buffer, nDataSize, wszText, STREAMIN_BUFFER_SIZE); + nWideChars = MultiByteToWideChar(CP_ACP, 0, stream->buffer, stream->dwSize, wszText, STREAMIN_BUFFER_SIZE); + pText = wszText; } else - nWideChars = nDataSize>>1; - ME_InsertTextFromCursor(editor, 0, wszText, nWideChars, style); - if (nDataSize<STREAMIN_BUFFER_SIZE) + { + nWideChars = stream->dwSize >> 1; + pText = (WCHAR *)stream->buffer; + } + + ME_InsertTextFromCursor(editor, 0, pText, nWideChars, style); + if (stream->dwSize < STREAMIN_BUFFER_SIZE) break; } while(1); ME_CommitUndo(editor); @@ -428,6 +432,16 @@ void ME_RTFReadHook(RTF_Info *info) { } }
+void +ME_StreamInFill(ME_InStream *stream) +{ + stream->editstream->dwError = stream->editstream->pfnCallback(stream->editstream->dwCookie, + stream->buffer, + sizeof(stream->buffer), + &stream->dwSize); + stream->dwUsed = 0; +} + static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stream) { RTF_Info parser; @@ -435,6 +449,7 @@ static LRESULT ME_StreamIn(ME_TextEditor int from, to, to2, nUndoMode; ME_UndoItem *pUI; int nEventMask = editor->nEventMask; + ME_InStream inStream;
TRACE("%p %p\n", stream, editor->hWnd); editor->nEventMask = 0; @@ -457,37 +472,60 @@ static LRESULT ME_StreamIn(ME_TextEditor
nUndoMode = editor->nUndoMode; editor->nUndoMode = umIgnore; - if (format & SF_RTF) { - /* setup the RTF parser */ - memset(&parser, 0, sizeof parser); - RTFSetEditStream(&parser, stream); - parser.rtfFormat = format&(SF_TEXT|SF_RTF); - parser.hwndEdit = editor->hWnd; - parser.editor = editor; - parser.style = style; - WriterInit(&parser); - RTFInit(&parser); - RTFSetReadHook(&parser, ME_RTFReadHook); - BeginFile(&parser); - - /* do the parsing */ - RTFRead(&parser); - RTFFlushOutputBuffer(&parser); - RTFDestroy(&parser); - - style = parser.style; - } - else if (format & SF_TEXT) - ME_StreamInText(editor, format, stream, style); - else - ERR("EM_STREAMIN without SF_TEXT or SF_RTF\n"); - ME_GetSelection(editor, &to, &to2); - /* put the cursor at the top */ - if (!(format & SFF_SELECTION)) - SendMessageA(editor->hWnd, EM_SETSEL, 0, 0); - else + + inStream.editstream = stream; + inStream.editstream->dwError = 0; + inStream.dwSize = 0; + inStream.dwUsed = 0; + + if (format & SF_RTF) { - /* FIXME where to put cursor now ? */ + /* Check if it's really RTF, and if it is not, use plain text */ + ME_StreamInFill(&inStream); + if (!inStream.editstream->dwError) + { + if (strncmp(inStream.buffer, "{\\rtf1", 6) && strncmp(inStream.buffer, "{\\urtf", 6)) + { + format &= ~SF_RTF; + format |= SF_TEXT; + } + } + } + + if (!inStream.editstream->dwError) + { + if (format & SF_RTF) { + /* setup the RTF parser */ + memset(&parser, 0, sizeof parser); + RTFSetEditStream(&parser, &inStream); + parser.rtfFormat = format&(SF_TEXT|SF_RTF); + parser.hwndEdit = editor->hWnd; + parser.editor = editor; + parser.style = style; + WriterInit(&parser); + RTFInit(&parser); + RTFSetReadHook(&parser, ME_RTFReadHook); + BeginFile(&parser); + + /* do the parsing */ + RTFRead(&parser); + RTFFlushOutputBuffer(&parser); + RTFDestroy(&parser); + + style = parser.style; + } + else if (format & SF_TEXT) + ME_StreamInText(editor, format, &inStream, style); + else + ERR("EM_STREAMIN without SF_TEXT or SF_RTF\n"); + ME_GetSelection(editor, &to, &to2); + /* put the cursor at the top */ + if (!(format & SFF_SELECTION)) + SendMessageA(editor->hWnd, EM_SETSEL, 0, 0); + else + { + /* FIXME where to put cursor now ? */ + } }
editor->nUndoMode = nUndoMode; Index: dlls/riched20/editor.h =================================================================== RCS file: /home/wine/wine/dlls/riched20/editor.h,v retrieving revision 1.12 diff -p -u -r1.12 editor.h --- dlls/riched20/editor.h 24 Mar 2005 21:01:37 -0000 1.12 +++ dlls/riched20/editor.h 13 Apr 2005 07:13:21 -0000 @@ -213,6 +213,7 @@ void ME_Redo(ME_TextEditor *editor); void ME_EmptyUndoStack(ME_TextEditor *editor); int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, BOOL bCRLF); ME_DisplayItem *ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int *nItemOffset); +void ME_StreamInFill(ME_InStream *stream);
extern int me_debug; extern HANDLE me_heap; Index: dlls/riched20/editstr.h =================================================================== RCS file: /home/wine/wine/dlls/riched20/editstr.h,v retrieving revision 1.8 diff -p -u -r1.8 editstr.h --- dlls/riched20/editstr.h 22 Mar 2005 16:41:36 -0000 1.8 +++ dlls/riched20/editstr.h 13 Apr 2005 07:13:21 -0000 @@ -197,6 +197,18 @@ typedef struct tagME_FontTableItem { WCHAR *szFaceName; } ME_FontTableItem;
+ +#define STREAMIN_BUFFER_SIZE 4096 /* M$ compatibility */ + +struct tagME_InStream { + EDITSTREAM *editstream; + DWORD dwSize; + DWORD dwUsed; + BYTE buffer[STREAMIN_BUFFER_SIZE]; +}; +typedef struct tagME_InStream ME_InStream; + + #define STREAMOUT_BUFFER_SIZE 4096 #define STREAMOUT_FONTTBL_SIZE 8192 #define STREAMOUT_COLORTBL_SIZE 1024 Index: dlls/riched20/reader.c =================================================================== RCS file: /home/wine/wine/dlls/riched20/reader.c,v retrieving revision 1.11 diff -p -u -r1.11 reader.c --- dlls/riched20/reader.c 22 Mar 2005 16:41:36 -0000 1.11 +++ dlls/riched20/reader.c 13 Apr 2005 07:13:21 -0000 @@ -123,41 +123,35 @@ static inline void RTFFree(void *p) int _RTFGetChar(RTF_Info *info) { int ch; + ME_InStream *stream = info->stream;
TRACE("\n");
/* if the last buffer wasn't full, it's EOF */ - if (info->dwInputSize > 0 && - info->dwInputSize == info->dwInputUsed && - info->dwInputSize < sizeof(info->InputBuffer)) + if (stream->dwSize > 0 && stream->dwSize == stream->dwUsed + && stream->dwSize < sizeof(stream->buffer)) return EOF; - if (info->dwInputSize <= info->dwInputUsed) + if (stream->dwSize <= stream->dwUsed) { - long count = 0; - info->editstream.dwError = info->editstream.pfnCallback(info->editstream.dwCookie, - info->InputBuffer, sizeof(info->InputBuffer), &count); + ME_StreamInFill(stream); /* if error, it's EOF */ - if (info->editstream.dwError) + if (stream->editstream->dwError) return EOF; /* if no bytes read, it's EOF */ - if (count == 0) + if (stream->dwSize == 0) return EOF; - info->dwInputSize = count; - info->dwInputUsed = 0; } - ch = info->InputBuffer[info->dwInputUsed++]; + ch = stream->buffer[stream->dwUsed++]; if (!ch) return EOF; return ch; }
-void RTFSetEditStream(RTF_Info *info, EDITSTREAM *es) +void RTFSetEditStream(RTF_Info *info, ME_InStream *stream) { TRACE("\n");
- info->editstream.dwCookie = es->dwCookie; - info->editstream.dwError = es->dwError; - info->editstream.pfnCallback = es->pfnCallback; + info->stream = stream; }
static void Index: dlls/riched20/rtf.h =================================================================== RCS file: /home/wine/wine/dlls/riched20/rtf.h,v retrieving revision 1.9 diff -p -u -r1.9 rtf.h --- dlls/riched20/rtf.h 22 Mar 2005 16:41:36 -0000 1.9 +++ dlls/riched20/rtf.h 13 Apr 2005 07:13:21 -0000 @@ -1078,10 +1078,7 @@ struct _RTF_Info { char *inputName; char *outputName;
- EDITSTREAM editstream; - char InputBuffer[0x1000]; - DWORD dwInputSize; - DWORD dwInputUsed; + ME_InStream *stream;
/* edit window to output to */ HWND hwndEdit; @@ -1155,7 +1152,7 @@ void RTFMsg (RTF_Info *, const char *fmt void RTFPanic (RTF_Info *, const char *fmt, ...);
void RTFFlushOutputBuffer( RTF_Info *info ); -void RTFSetEditStream(RTF_Info *, EDITSTREAM *es); +void RTFSetEditStream(RTF_Info *info, ME_InStream *stream);
void WriterInit (RTF_Info *); int BeginFile (RTF_Info *);
Is this a problem with the current CVS of the last few days since I'm having some problems around riched20 with the ie6 setup myself. Bob On Wed, 20 Apr 2005 04:31 pm, Mike McCormack wrote:
Hi Phil,
This patch broke Internet Explorer 6 installation. The installer gets into an infinite loop reading the License text for the first dialog.
Mike
Phil Krylov wrote:
Hi,
this version of patch is made against current CVS.
ChangeLog:
Make RTF reader fall back to simple text if a correct RTF header is not detected. This should fix some installers.
Patch:
Index: dlls/riched20/editor.c =================================================================== RCS file: /home/wine/wine/dlls/riched20/editor.c,v retrieving revision 1.22 diff -p -u -r1.22 editor.c --- dlls/riched20/editor.c 11 Apr 2005 14:22:21 -0000 1.22 +++ dlls/riched20/editor.c 13 Apr 2005 07:13:21 -0000 @@ -233,36 +233,40 @@ ME_TextBuffer *ME_MakeText() { return buf; }
-#define STREAMIN_BUFFER_SIZE 4096 /* M$ compatibility */
-static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream, ME_Style *style) +static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, ME_InStream *stream, ME_Style *style) { - BYTE buffer[STREAMIN_BUFFER_SIZE+1]; WCHAR wszText[STREAMIN_BUFFER_SIZE+1]; + WCHAR *pText;
TRACE("%08lx %p\n", dwFormat, stream); - stream->dwError = 0;
do { - long nDataSize = 0, nWideChars = 0; - stream->dwError = stream->pfnCallback(stream->dwCookie, - (dwFormat & SF_UNICODE ? (BYTE *)wszText : buffer), - STREAMIN_BUFFER_SIZE, &nDataSize); - - if (stream->dwError) - break; - if (!nDataSize) - break; + long nWideChars = 0; + + if (!stream->dwSize) + { + ME_StreamInFill(stream); + if (stream->editstream->dwError) + break; + if (!stream->dwSize) + break; + }
if (!(dwFormat & SF_UNICODE)) { /* FIXME? this is doomed to fail on true MBCS like UTF-8, luckily they're unlikely to be used as CP_ACP */ - nWideChars = MultiByteToWideChar(CP_ACP, 0, buffer, nDataSize, wszText, STREAMIN_BUFFER_SIZE); + nWideChars = MultiByteToWideChar(CP_ACP, 0, stream->buffer, stream->dwSize, wszText, STREAMIN_BUFFER_SIZE); + pText = wszText; } else - nWideChars = nDataSize>>1; - ME_InsertTextFromCursor(editor, 0, wszText, nWideChars, style); - if (nDataSize<STREAMIN_BUFFER_SIZE) + { + nWideChars = stream->dwSize >> 1; + pText = (WCHAR *)stream->buffer; + } + + ME_InsertTextFromCursor(editor, 0, pText, nWideChars, style); + if (stream->dwSize < STREAMIN_BUFFER_SIZE) break; } while(1); ME_CommitUndo(editor); @@ -428,6 +432,16 @@ void ME_RTFReadHook(RTF_Info *info) { } }
+void +ME_StreamInFill(ME_InStream *stream) +{ + stream->editstream->dwError = stream->editstream->pfnCallback(stream->editstream->dwCookie, + stream->buffer, +
sizeof(stream->buffer), + &stream->dwSize); + stream->dwUsed = 0; +} + static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stream) { RTF_Info parser; @@ -435,6 +449,7 @@ static LRESULT ME_StreamIn(ME_TextEditor int from, to, to2, nUndoMode; ME_UndoItem *pUI; int nEventMask = editor->nEventMask; + ME_InStream inStream;
TRACE("%p %p\n", stream, editor->hWnd); editor->nEventMask = 0; @@ -457,37 +472,60 @@ static LRESULT ME_StreamIn(ME_TextEditor
nUndoMode = editor->nUndoMode; editor->nUndoMode = umIgnore; - if (format & SF_RTF) { - /* setup the RTF parser */ - memset(&parser, 0, sizeof parser); - RTFSetEditStream(&parser, stream); - parser.rtfFormat = format&(SF_TEXT|SF_RTF); - parser.hwndEdit = editor->hWnd; - parser.editor = editor; - parser.style = style; - WriterInit(&parser); - RTFInit(&parser); - RTFSetReadHook(&parser, ME_RTFReadHook); - BeginFile(&parser); - - /* do the parsing */ - RTFRead(&parser); - RTFFlushOutputBuffer(&parser); - RTFDestroy(&parser); - - style = parser.style; - } - else if (format & SF_TEXT) - ME_StreamInText(editor, format, stream, style); - else - ERR("EM_STREAMIN without SF_TEXT or SF_RTF\n"); - ME_GetSelection(editor, &to, &to2); - /* put the cursor at the top */ - if (!(format & SFF_SELECTION)) - SendMessageA(editor->hWnd, EM_SETSEL, 0, 0); - else + + inStream.editstream = stream; + inStream.editstream->dwError = 0; + inStream.dwSize = 0; + inStream.dwUsed = 0; + + if (format & SF_RTF) { - /* FIXME where to put cursor now ? */ + /* Check if it's really RTF, and if it is not, use plain text */ + ME_StreamInFill(&inStream); + if (!inStream.editstream->dwError) + { + if (strncmp(inStream.buffer, "{\\rtf1", 6) && strncmp(inStream.buffer, "{\\urtf", 6)) + { + format &= ~SF_RTF; + format |= SF_TEXT; + } + } + } + + if (!inStream.editstream->dwError) + { + if (format & SF_RTF) { + /* setup the RTF parser */ + memset(&parser, 0, sizeof parser); + RTFSetEditStream(&parser, &inStream); + parser.rtfFormat = format&(SF_TEXT|SF_RTF); + parser.hwndEdit = editor->hWnd; + parser.editor = editor; + parser.style = style; + WriterInit(&parser); + RTFInit(&parser); + RTFSetReadHook(&parser, ME_RTFReadHook); + BeginFile(&parser); + + /* do the parsing */ + RTFRead(&parser); + RTFFlushOutputBuffer(&parser); + RTFDestroy(&parser); + + style = parser.style; + } + else if (format & SF_TEXT) + ME_StreamInText(editor, format, &inStream, style); + else + ERR("EM_STREAMIN without SF_TEXT or SF_RTF\n"); + ME_GetSelection(editor, &to, &to2); + /* put the cursor at the top */ + if (!(format & SFF_SELECTION)) + SendMessageA(editor->hWnd, EM_SETSEL, 0, 0); + else + { + /* FIXME where to put cursor now ? */ + } }
editor->nUndoMode = nUndoMode; Index: dlls/riched20/editor.h =================================================================== RCS file: /home/wine/wine/dlls/riched20/editor.h,v retrieving revision 1.12 diff -p -u -r1.12 editor.h --- dlls/riched20/editor.h 24 Mar 2005 21:01:37 -0000 1.12 +++ dlls/riched20/editor.h 13 Apr 2005 07:13:21 -0000 @@ -213,6 +213,7 @@ void ME_Redo(ME_TextEditor *editor); void ME_EmptyUndoStack(ME_TextEditor *editor); int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, BOOL bCRLF); ME_DisplayItem *ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int *nItemOffset); +void ME_StreamInFill(ME_InStream *stream);
extern int me_debug; extern HANDLE me_heap; Index: dlls/riched20/editstr.h =================================================================== RCS file: /home/wine/wine/dlls/riched20/editstr.h,v retrieving revision 1.8 diff -p -u -r1.8 editstr.h --- dlls/riched20/editstr.h 22 Mar 2005 16:41:36 -0000 1.8 +++ dlls/riched20/editstr.h 13 Apr 2005 07:13:21 -0000 @@ -197,6 +197,18 @@ typedef struct tagME_FontTableItem { WCHAR *szFaceName; } ME_FontTableItem;
+ +#define STREAMIN_BUFFER_SIZE 4096 /* M$ compatibility */ + +struct tagME_InStream { + EDITSTREAM *editstream; + DWORD dwSize; + DWORD dwUsed; + BYTE buffer[STREAMIN_BUFFER_SIZE]; +}; +typedef struct tagME_InStream ME_InStream; + + #define STREAMOUT_BUFFER_SIZE 4096 #define STREAMOUT_FONTTBL_SIZE 8192 #define STREAMOUT_COLORTBL_SIZE 1024 Index: dlls/riched20/reader.c =================================================================== RCS file: /home/wine/wine/dlls/riched20/reader.c,v retrieving revision 1.11 diff -p -u -r1.11 reader.c --- dlls/riched20/reader.c 22 Mar 2005 16:41:36 -0000 1.11 +++ dlls/riched20/reader.c 13 Apr 2005 07:13:21 -0000 @@ -123,41 +123,35 @@ static inline void RTFFree(void *p) int _RTFGetChar(RTF_Info *info) { int ch; + ME_InStream *stream = info->stream;
TRACE("\n");
/* if the last buffer wasn't full, it's EOF */ - if (info->dwInputSize > 0 && - info->dwInputSize == info->dwInputUsed && - info->dwInputSize < sizeof(info->InputBuffer)) + if (stream->dwSize > 0 && stream->dwSize == stream->dwUsed + && stream->dwSize < sizeof(stream->buffer)) return EOF; - if (info->dwInputSize <= info->dwInputUsed) + if (stream->dwSize <= stream->dwUsed) { - long count = 0; - info->editstream.dwError = info->editstream.pfnCallback(info->editstream.dwCookie, - info->InputBuffer, sizeof(info->InputBuffer), &count); + ME_StreamInFill(stream); /* if error, it's EOF */ - if (info->editstream.dwError) + if (stream->editstream->dwError) return EOF; /* if no bytes read, it's EOF */ - if (count == 0) + if (stream->dwSize == 0) return EOF; - info->dwInputSize = count; - info->dwInputUsed = 0; } - ch = info->InputBuffer[info->dwInputUsed++]; + ch = stream->buffer[stream->dwUsed++]; if (!ch) return EOF; return ch; }
-void RTFSetEditStream(RTF_Info *info, EDITSTREAM *es) +void RTFSetEditStream(RTF_Info *info, ME_InStream *stream) { TRACE("\n");
- info->editstream.dwCookie = es->dwCookie; - info->editstream.dwError = es->dwError; - info->editstream.pfnCallback = es->pfnCallback; + info->stream = stream; }
static void Index: dlls/riched20/rtf.h =================================================================== RCS file: /home/wine/wine/dlls/riched20/rtf.h,v retrieving revision 1.9 diff -p -u -r1.9 rtf.h --- dlls/riched20/rtf.h 22 Mar 2005 16:41:36 -0000 1.9 +++ dlls/riched20/rtf.h 13 Apr 2005 07:13:21 -0000 @@ -1078,10 +1078,7 @@ struct _RTF_Info { char *inputName; char *outputName;
- EDITSTREAM editstream; - char InputBuffer[0x1000]; - DWORD dwInputSize; - DWORD dwInputUsed; + ME_InStream *stream;
/* edit window to output to */ HWND hwndEdit; @@ -1155,7 +1152,7 @@ void RTFMsg (RTF_Info *, const char *fmt void RTFPanic (RTF_Info *, const char *fmt, ...);
void RTFFlushOutputBuffer( RTF_Info *info ); -void RTFSetEditStream(RTF_Info *, EDITSTREAM *es); +void RTFSetEditStream(RTF_Info *info, ME_InStream *stream);
void WriterInit (RTF_Info *); int BeginFile (RTF_Info *);
Hi, On Wed, 20 Apr 2005 04:31 pm, Mike McCormack wrote:
Hi Phil,
This patch broke Internet Explorer 6 installation. The installer gets into an infinite loop reading the License text for the first dialog.
Mike
Sorry. See the fix on wine-patches. -- Ph.
Phil Krylov wrote:
This patch broke Internet Explorer 6 installation. The installer gets into an infinite loop reading the License text for the first dialog.
Sorry. See the fix on wine-patches.
You've done great work, and I thought you would want to know about a problem with it so you could correct it. No need for "sorry" :) thanks for the awesome work, Mike
On Thu, 21 Apr 2005 00:58:10 +0900 Mike McCormack <mike(a)codeweavers.com> wrote:
You've done great work, and I thought you would want to know about a problem with it so you could correct it. No need for "sorry" :)
I wrote "sorry" because I feel sorry :) I should give a more thorough testing to this code. -- Ph.
participants (3)
-
Mike McCormack -
Phil Krylov -
Robert Lunnon