]>
Commit | Line | Data |
---|---|---|
05649561 AG |
1 | To: vim-dev@vim.org |
2 | Subject: Patch 6.2.230 (extra) | |
3 | Fcc: outbox | |
4 | From: Bram Moolenaar <Bram@moolenaar.net> | |
5 | Mime-Version: 1.0 | |
6 | Content-Type: text/plain; charset=ISO-8859-1 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ------------ | |
9 | ||
10 | Patch 6.2.230 (extra) | |
11 | Problem: Win32: a complex pattern may cause a crash. | |
12 | Solution: Use __try and __except to catch the exception and handle it | |
13 | gracefully, when possible. Add myresetstkoflw() to reset the | |
14 | stack overflow. (Benjamin Peterson) | |
15 | Files: src/Make_bc5.mak, src/os_mswin.c src/os_win32.c, src/os_win32.h, | |
16 | src/proto/os_win32.pro, src/regexp.c | |
17 | ||
18 | ||
19 | *** ../vim-6.2.229/src/Make_bc5.mak Tue Feb 3 16:20:37 2004 | |
20 | --- src/Make_bc5.mak Tue Feb 3 10:47:26 2004 | |
21 | *************** | |
22 | *** 488,494 **** | |
23 | CC = $(BOR)\BIN\Bcc32 | |
24 | LFLAGS = -OS -Tpe -c -m -L$(LIB) $(DEBUG_FLAG) $(LINK2) | |
25 | LFLAGSDLL = -Tpd -c -m -L$(LIB) $(DEBUG_FLAG) $(LINK2) | |
26 | ! CFLAGS = -w-aus -w-par -w-pch -I$(INCLUDE) -d -x- -RT- -k- -Oi $(HEADERS) -f- | |
27 | !endif | |
28 | ||
29 | CC1 = -c | |
30 | --- 488,494 ---- | |
31 | CC = $(BOR)\BIN\Bcc32 | |
32 | LFLAGS = -OS -Tpe -c -m -L$(LIB) $(DEBUG_FLAG) $(LINK2) | |
33 | LFLAGSDLL = -Tpd -c -m -L$(LIB) $(DEBUG_FLAG) $(LINK2) | |
34 | ! CFLAGS = -w-aus -w-par -w-pch -I$(INCLUDE) -d -RT- -k- -Oi $(HEADERS) -f- | |
35 | !endif | |
36 | ||
37 | CC1 = -c | |
38 | *** ../vim-6.2.229/src/os_mswin.c Sun Oct 12 16:42:14 2003 | |
39 | --- src/os_mswin.c Sun Feb 1 17:18:09 2004 | |
40 | *************** | |
41 | *** 738,743 **** | |
42 | --- 738,747 ---- | |
43 | // If the handle is valid, try to get the function address. | |
44 | if (hinstLib != NULL) | |
45 | { | |
46 | + #ifdef HAVE_TRY_EXCEPT | |
47 | + __try | |
48 | + { | |
49 | + #endif | |
50 | if (argstring != NULL) | |
51 | { | |
52 | /* Call with string argument */ | |
53 | *************** | |
54 | *** 782,787 **** | |
55 | --- 786,801 ---- | |
56 | if (*string_result != NULL) | |
57 | mch_memmove(*string_result, retval_str, len); | |
58 | } | |
59 | + | |
60 | + #ifdef HAVE_TRY_EXCEPT | |
61 | + } | |
62 | + __except(EXCEPTION_EXECUTE_HANDLER) | |
63 | + { | |
64 | + if (GetExceptionCode() == EXCEPTION_STACK_OVERFLOW) | |
65 | + RESETSTKOFLW(); | |
66 | + fRunTimeLinkSuccess = 0; | |
67 | + } | |
68 | + #endif | |
69 | ||
70 | // Free the DLL module. | |
71 | (void)FreeLibrary(hinstLib); | |
72 | *** ../vim-6.2.229/src/os_win32.c Sun Oct 26 20:15:06 2003 | |
73 | --- src/os_win32.c Sun Feb 1 17:37:49 2004 | |
74 | *************** | |
75 | *** 4202,4204 **** | |
76 | --- 4203,4312 ---- | |
77 | { | |
78 | return copy_infostreams(from, to); | |
79 | } | |
80 | + | |
81 | + #if defined(MYRESETSTKOFLW) || defined(PROTO) | |
82 | + /* | |
83 | + * Recreate a destroyed stack guard page in win32. | |
84 | + * Written by Benjamin Peterson. | |
85 | + */ | |
86 | + | |
87 | + /* These magic numbers are from the MS header files */ | |
88 | + #define MIN_STACK_WIN9X 17 | |
89 | + #define MIN_STACK_WINNT 2 | |
90 | + | |
91 | + /* | |
92 | + * This function does the same thing as _resetstkoflw(), which is only | |
93 | + * available in DevStudio .net and later. | |
94 | + * Returns 0 for failure, 1 for success. | |
95 | + */ | |
96 | + int | |
97 | + myresetstkoflw(void) | |
98 | + { | |
99 | + BYTE *pStackPtr; | |
100 | + BYTE *pGuardPage; | |
101 | + BYTE *pStackBase; | |
102 | + BYTE *pLowestPossiblePage; | |
103 | + MEMORY_BASIC_INFORMATION mbi; | |
104 | + SYSTEM_INFO si; | |
105 | + DWORD nPageSize; | |
106 | + DWORD dummy; | |
107 | + | |
108 | + /* This code will not work on win32s. */ | |
109 | + PlatformId(); | |
110 | + if (g_PlatformId == VER_PLATFORM_WIN32s) | |
111 | + return 0; | |
112 | + | |
113 | + /* We need to know the system page size. */ | |
114 | + GetSystemInfo(&si); | |
115 | + nPageSize = si.dwPageSize; | |
116 | + | |
117 | + /* ...and the current stack pointer */ | |
118 | + pStackPtr = (BYTE*)_alloca(1); | |
119 | + | |
120 | + /* ...and the base of the stack. */ | |
121 | + if (VirtualQuery(pStackPtr, &mbi, sizeof mbi) == 0) | |
122 | + return 0; | |
123 | + pStackBase = (BYTE*)mbi.AllocationBase; | |
124 | + | |
125 | + /* ...and the page thats min_stack_req pages away from stack base; this is | |
126 | + * the lowest page we could use. */ | |
127 | + pLowestPossiblePage = pStackBase + ((g_PlatformId == VER_PLATFORM_WIN32_NT) | |
128 | + ? MIN_STACK_WINNT : MIN_STACK_WIN9X) * nPageSize; | |
129 | + | |
130 | + /* On Win95, we want the next page down from the end of the stack. */ | |
131 | + if (g_PlatformId == VER_PLATFORM_WIN32_WINDOWS) | |
132 | + { | |
133 | + /* Find the page that's only 1 page down from the page that the stack | |
134 | + * ptr is in. */ | |
135 | + pGuardPage = (BYTE*)((DWORD)nPageSize * (((DWORD)pStackPtr | |
136 | + / (DWORD)nPageSize) - 1)); | |
137 | + if (pGuardPage < pLowestPossiblePage) | |
138 | + return 0; | |
139 | + | |
140 | + /* Apply the noaccess attribute to the page -- there's no guard | |
141 | + * attribute in win95-type OSes. */ | |
142 | + if (!VirtualProtect(pGuardPage, nPageSize, PAGE_NOACCESS, &dummy)) | |
143 | + return 0; | |
144 | + } | |
145 | + else | |
146 | + { | |
147 | + /* On NT, however, we want the first committed page in the stack Start | |
148 | + * at the stack base and move forward through memory until we find a | |
149 | + * committed block. */ | |
150 | + BYTE *pBlock = pStackBase; | |
151 | + | |
152 | + while (1) | |
153 | + { | |
154 | + if (VirtualQuery(pBlock, &mbi, sizeof mbi) == 0) | |
155 | + return 0; | |
156 | + | |
157 | + pBlock += mbi.RegionSize; | |
158 | + | |
159 | + if (mbi.State & MEM_COMMIT) | |
160 | + break; | |
161 | + } | |
162 | + | |
163 | + /* mbi now describes the first committed block in the stack. */ | |
164 | + if (mbi.Protect & PAGE_GUARD) | |
165 | + return 1; | |
166 | + | |
167 | + /* decide where the guard page should start */ | |
168 | + if ((long_u)(mbi.BaseAddress) < (long_u)pLowestPossiblePage) | |
169 | + pGuardPage = pLowestPossiblePage; | |
170 | + else | |
171 | + pGuardPage = (BYTE*)mbi.BaseAddress; | |
172 | + | |
173 | + /* allocate the guard page */ | |
174 | + if (!VirtualAlloc(pGuardPage, nPageSize, MEM_COMMIT, PAGE_READWRITE)) | |
175 | + return 0; | |
176 | + | |
177 | + /* apply the guard attribute to the page */ | |
178 | + if (!VirtualProtect(pGuardPage, nPageSize, PAGE_READWRITE | PAGE_GUARD, | |
179 | + &dummy)) | |
180 | + return 0; | |
181 | + } | |
182 | + | |
183 | + return 1; | |
184 | + } | |
185 | + | |
186 | + #endif | |
187 | *** ../vim-6.2.229/src/os_win32.h Sun Oct 12 16:42:14 2003 | |
188 | --- src/os_win32.h Sun Feb 1 17:49:34 2004 | |
189 | *************** | |
190 | *** 117,122 **** | |
191 | --- 117,135 ---- | |
192 | # define DFLT_MAXMEMTOT (5*1024) /* use up to 5 Mbyte for Vim */ | |
193 | #endif | |
194 | ||
195 | + #if defined(_MSC_VER) || defined(__BORLANDC__) | |
196 | + /* Support for __try / __except. All versions of MSVC and Borland C are | |
197 | + * expected to have this. Any other compilers that support it? */ | |
198 | + # define HAVE_TRY_EXCEPT 1 | |
199 | + # include <malloc.h> /* for _resetstkoflw() */ | |
200 | + # if defined(_MSC_VER) && (_MSC_VER >= 1300) | |
201 | + # define RESETSTKOFLW _resetstkoflw | |
202 | + # else | |
203 | + # define RESETSTKOFLW myresetstkoflw | |
204 | + # define MYRESETSTKOFLW | |
205 | + # endif | |
206 | + #endif | |
207 | + | |
208 | /* | |
209 | * Some simple debugging macros that look and behave a lot like their | |
210 | * namesakes in MFC. | |
211 | *** ../vim-6.2.229/src/proto/os_win32.pro Sun Jun 1 12:26:30 2003 | |
212 | --- src/proto/os_win32.pro Sun Feb 1 17:32:46 2004 | |
213 | *************** | |
214 | *** 41,44 **** | |
215 | --- 41,45 ---- | |
216 | char *default_shell __ARGS((void)); | |
217 | int mch_access __ARGS((char *n, int p)); | |
218 | int mch_copy_file_attribute __ARGS((char_u *from, char_u *to)); | |
219 | + int myresetstkoflw __ARGS((void)); | |
220 | /* vim: set ft=c : */ | |
221 | *** ../vim-6.2.229/src/regexp.c Sat Sep 27 19:36:47 2003 | |
222 | --- src/regexp.c Sun Feb 1 17:50:16 2004 | |
223 | *************** | |
224 | *** 2784,2789 **** | |
225 | --- 2784,2795 ---- | |
226 | #endif | |
227 | ||
228 | reg_tofree = NULL; | |
229 | + | |
230 | + #ifdef HAVE_TRY_EXCEPT | |
231 | + __try | |
232 | + { | |
233 | + #endif | |
234 | + | |
235 | #ifdef HAVE_SETJMP_H | |
236 | /* | |
237 | * Matching with a regexp may cause a very deep recursive call of | |
238 | *************** | |
239 | *** 2939,2944 **** | |
240 | --- 2945,2965 ---- | |
241 | ||
242 | if (out_of_stack) | |
243 | EMSG(_("E363: pattern caused out-of-stack error")); | |
244 | + | |
245 | + #ifdef HAVE_TRY_EXCEPT | |
246 | + } | |
247 | + __except(EXCEPTION_EXECUTE_HANDLER) | |
248 | + { | |
249 | + if (GetExceptionCode() == EXCEPTION_STACK_OVERFLOW) | |
250 | + { | |
251 | + RESETSTKOFLW(); | |
252 | + EMSG(_("E363: pattern caused out-of-stack error")); | |
253 | + } | |
254 | + else | |
255 | + EMSG(_("E361: Crash intercepted; regexp too complex?")); | |
256 | + retval = 0L; | |
257 | + } | |
258 | + #endif | |
259 | ||
260 | theend: | |
261 | /* Didn't find a match. */ | |
262 | *** ../vim-6.2.229/src/version.c Tue Feb 3 16:33:22 2004 | |
263 | --- src/version.c Tue Feb 3 16:52:46 2004 | |
264 | *************** | |
265 | *** 639,640 **** | |
266 | --- 639,642 ---- | |
267 | { /* Add new patch number below this line */ | |
268 | + /**/ | |
269 | + 230, | |
270 | /**/ | |
271 | ||
272 | -- | |
273 | What a wonderfully exciting cough! Do you mind if I join you? | |
274 | -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy" | |
275 | ||
276 | /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ | |
277 | /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ | |
278 | \\\ Project leader for A-A-P -- http://www.A-A-P.org /// | |
279 | \\\ Help AIDS victims, buy here: http://ICCF-Holland.org/click1.html /// |