Fixed buffer overflow.
[wine] / dlls / gdi / bidi.c
1
2 /*
3  * GDI BiDirectional handling
4  *
5  * Copyright 2003 Shachar Shemesh
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23
24 #include <stdarg.h>
25 #ifdef HAVE_UNICODE_UBIDI_H
26 #include <unicode/ubidi.h>
27 #endif
28
29 #include "windef.h"
30 #include "winbase.h"
31 #include "wingdi.h"
32 #include "wine/debug.h"
33 #include "gdi.h"
34 #include "gdi_private.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(bidi);
37
38 #ifdef HAVE_ICU
39 BOOL BidiAvail = TRUE;
40 #else
41 BOOL BidiAvail = FALSE;
42 #endif
43
44
45 /*************************************************************
46  *    BIDI_Reorder
47  */
48 BOOL BIDI_Reorder(
49                 LPCWSTR lpString,       /* [in] The string for which information is to be returned */
50                 INT uCount,     /* [in] Number of WCHARs in string. */
51                 DWORD dwFlags,  /* [in] GetCharacterPlacement compatible flags specifying how to process the string */
52                 DWORD dwWineGCP_Flags,       /* [in] Wine internal flags - Force paragraph direction */
53                 LPWSTR lpOutString, /* [out] Reordered string */
54                 INT uCountOut,  /* [in] Size of output buffer */
55                 UINT *lpOrder /* [out] Logical -> Visual order map */
56     )
57 {
58 #ifdef HAVE_ICU
59     TRACE("%s, %d, 0x%08lx lpOutString=%p, lpOrder=%p\n",
60           debugstr_wn(lpString, uCount), uCount, dwFlags,
61           lpOutString, lpOrder);
62
63     if ((dwFlags & GCP_REORDER) != 0) {
64         UBiDi *bidi;
65         UErrorCode err=0;
66         UBiDiLevel level=0;
67
68         bidi=ubidi_open();
69         if( bidi==NULL ) {
70             WARN("Failed to allocate structure\n");
71             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
72             return FALSE;
73         }
74
75         switch( dwWineGCP_Flags&WINE_GCPW_DIR_MASK )
76         {
77         case WINE_GCPW_FORCE_LTR:
78             level=0;
79             break;
80         case WINE_GCPW_FORCE_RTL:
81             level=1;
82             break;
83         case WINE_GCPW_LOOSE_LTR:
84             level=UBIDI_DEFAULT_LTR;
85             break;
86         case WINE_GCPW_LOOSE_RTL:
87             level=UBIDI_DEFAULT_RTL;
88             break;
89         }
90
91         ubidi_setPara( bidi, lpString, uCount, level, NULL, &err );
92         if( lpOutString!=NULL ) {
93             ubidi_writeReordered( bidi, lpOutString, uCount,
94                     (dwFlags&GCP_SYMSWAPOFF)?0:UBIDI_DO_MIRRORING, &err );
95         }
96
97         if( lpOrder!=NULL ) {
98             ubidi_getLogicalMap( bidi, lpOrder, &err );
99         }
100
101         ubidi_close( bidi );
102
103         if( U_FAILURE(err) ) {
104             FIXME("ICU Library return error code %d.\n", err );
105             FIXME("Please report this error to wine-devel@winehq.org so we can place "
106                     "descriptive Windows error codes here\n");
107             SetLastError(ERROR_INVALID_LEVEL); /* This error is cryptic enough not to mean anything, I hope */
108
109             return FALSE;
110         }
111     }
112     return TRUE;
113 #else  /* HAVE_ICU */
114     return FALSE;
115 #endif  /* HAVE_ICU */
116 }