Resend: RICHED20: fall back to simple test

Mike McCormack mike at codeweavers.com
Wed Apr 20 01:31:56 CDT 2005


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 *);
> 



More information about the wine-devel mailing list