]>
Commit | Line | Data |
---|---|---|
ef0610d1 AG |
1 | To: vim-dev@vim.org |
2 | Subject: Patch 7.2.200 | |
3 | Fcc: outbox | |
4 | From: Bram Moolenaar <Bram@moolenaar.net> | |
5 | Mime-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ------------ | |
9 | ||
10 | Patch 7.2.200 | |
11 | Problem: Reading past end of string when navigating the menu bar or | |
12 | resizing the window. | |
13 | Solution: Add and use mb_ptr2len_len(). (partly by Dominique Pelle) | |
14 | Also add mb_ptr2cells_len() to prevent more trouble. | |
15 | Files: src/gui_gtk_x11.c, src/os_unix.c, src/globals.h, src/mbyte.c, | |
16 | src/proto/mbyte.pro | |
17 | ||
18 | ||
19 | *** ../vim-7.2.199/src/gui_gtk_x11.c 2009-06-03 16:20:09.000000000 +0200 | |
20 | --- src/gui_gtk_x11.c 2009-06-16 14:44:19.000000000 +0200 | |
21 | *************** | |
22 | *** 6077,6088 **** | |
23 | # ifdef FEAT_MBYTE | |
24 | if (enc_utf8) | |
25 | { | |
26 | ! c = utf_ptr2char(p); | |
27 | if (c >= 0x10000) /* show chars > 0xffff as ? */ | |
28 | c = 0xbf; | |
29 | buf[textlen].byte1 = c >> 8; | |
30 | buf[textlen].byte2 = c; | |
31 | ! p += utf_ptr2len(p); | |
32 | width += utf_char2cells(c); | |
33 | } | |
34 | else | |
35 | --- 6135,6149 ---- | |
36 | # ifdef FEAT_MBYTE | |
37 | if (enc_utf8) | |
38 | { | |
39 | ! int pcc[MAX_MCO]; | |
40 | ! | |
41 | ! /* TODO: use the composing characters */ | |
42 | ! c = utfc_ptr2char_len(p, &pcc, len - (p - s)); | |
43 | if (c >= 0x10000) /* show chars > 0xffff as ? */ | |
44 | c = 0xbf; | |
45 | buf[textlen].byte1 = c >> 8; | |
46 | buf[textlen].byte2 = c; | |
47 | ! p += utfc_ptr2len_len(p, len - (p - s)); | |
48 | width += utf_char2cells(c); | |
49 | } | |
50 | else | |
51 | *************** | |
52 | *** 6106,6113 **** | |
53 | if (has_mbyte) | |
54 | { | |
55 | width = 0; | |
56 | ! for (p = s; p < s + len; p += (*mb_ptr2len)(p)) | |
57 | ! width += (*mb_ptr2cells)(p); | |
58 | } | |
59 | else | |
60 | # endif | |
61 | --- 6167,6174 ---- | |
62 | if (has_mbyte) | |
63 | { | |
64 | width = 0; | |
65 | ! for (p = s; p < s + len; p += (*mb_ptr2len_len)(p, len - (p - s))) | |
66 | ! width += (*mb_ptr2cells_len)(p, len - (p - s)); | |
67 | } | |
68 | else | |
69 | # endif | |
70 | *** ../vim-7.2.199/src/os_unix.c 2009-05-17 13:30:58.000000000 +0200 | |
71 | --- src/os_unix.c 2009-06-03 12:35:59.000000000 +0200 | |
72 | *************** | |
73 | *** 4305,4311 **** | |
74 | ta_buf[i] = '\n'; | |
75 | # ifdef FEAT_MBYTE | |
76 | if (has_mbyte) | |
77 | ! i += (*mb_ptr2len)(ta_buf + i) - 1; | |
78 | # endif | |
79 | } | |
80 | ||
81 | --- 4305,4312 ---- | |
82 | ta_buf[i] = '\n'; | |
83 | # ifdef FEAT_MBYTE | |
84 | if (has_mbyte) | |
85 | ! i += (*mb_ptr2len_len)(ta_buf + i, | |
86 | ! ta_len + len - i) - 1; | |
87 | # endif | |
88 | } | |
89 | ||
90 | *** ../vim-7.2.199/src/globals.h 2009-06-10 18:15:49.000000000 +0200 | |
91 | --- src/globals.h 2009-06-12 21:10:30.000000000 +0200 | |
92 | *************** | |
93 | *** 810,820 **** | |
94 | --- 815,828 ---- | |
95 | */ | |
96 | /* length of char in bytes, including following composing chars */ | |
97 | EXTERN int (*mb_ptr2len) __ARGS((char_u *p)) INIT(= latin_ptr2len); | |
98 | + /* idem, with limit on string length */ | |
99 | + EXTERN int (*mb_ptr2len_len) __ARGS((char_u *p, int size)) INIT(= latin_ptr2len_len); | |
100 | /* byte length of char */ | |
101 | EXTERN int (*mb_char2len) __ARGS((int c)) INIT(= latin_char2len); | |
102 | /* convert char to bytes, return the length */ | |
103 | EXTERN int (*mb_char2bytes) __ARGS((int c, char_u *buf)) INIT(= latin_char2bytes); | |
104 | EXTERN int (*mb_ptr2cells) __ARGS((char_u *p)) INIT(= latin_ptr2cells); | |
105 | + EXTERN int (*mb_ptr2cells_len) __ARGS((char_u *p, int size)) INIT(= latin_ptr2cells_len); | |
106 | EXTERN int (*mb_char2cells) __ARGS((int c)) INIT(= latin_char2cells); | |
107 | EXTERN int (*mb_off2cells) __ARGS((unsigned off, unsigned max_off)) INIT(= latin_off2cells); | |
108 | EXTERN int (*mb_ptr2char) __ARGS((char_u *p)) INIT(= latin_ptr2char); | |
109 | *** ../vim-7.2.199/src/mbyte.c 2009-05-17 13:30:58.000000000 +0200 | |
110 | --- src/mbyte.c 2009-06-16 15:01:30.000000000 +0200 | |
111 | *************** | |
112 | *** 127,133 **** | |
113 | --- 127,136 ---- | |
114 | static int dbcs_char2len __ARGS((int c)); | |
115 | static int dbcs_char2bytes __ARGS((int c, char_u *buf)); | |
116 | static int dbcs_ptr2len __ARGS((char_u *p)); | |
117 | + static int dbcs_ptr2len_len __ARGS((char_u *p, int size)); | |
118 | + static int utf_ptr2cells_len __ARGS((char_u *p, int size)); | |
119 | static int dbcs_char2cells __ARGS((int c)); | |
120 | + static int dbcs_ptr2cells_len __ARGS((char_u *p, int size)); | |
121 | static int dbcs_ptr2char __ARGS((char_u *p)); | |
122 | ||
123 | /* Lookup table to quickly get the length in bytes of a UTF-8 character from | |
124 | *************** | |
125 | *** 606,614 **** | |
126 | --- 609,619 ---- | |
127 | if (enc_utf8) | |
128 | { | |
129 | mb_ptr2len = utfc_ptr2len; | |
130 | + mb_ptr2len_len = utfc_ptr2len_len; | |
131 | mb_char2len = utf_char2len; | |
132 | mb_char2bytes = utf_char2bytes; | |
133 | mb_ptr2cells = utf_ptr2cells; | |
134 | + mb_ptr2cells_len = utf_ptr2cells_len; | |
135 | mb_char2cells = utf_char2cells; | |
136 | mb_off2cells = utf_off2cells; | |
137 | mb_ptr2char = utf_ptr2char; | |
138 | *************** | |
139 | *** 617,625 **** | |
140 | --- 622,632 ---- | |
141 | else if (enc_dbcs != 0) | |
142 | { | |
143 | mb_ptr2len = dbcs_ptr2len; | |
144 | + mb_ptr2len_len = dbcs_ptr2len_len; | |
145 | mb_char2len = dbcs_char2len; | |
146 | mb_char2bytes = dbcs_char2bytes; | |
147 | mb_ptr2cells = dbcs_ptr2cells; | |
148 | + mb_ptr2cells_len = dbcs_ptr2cells_len; | |
149 | mb_char2cells = dbcs_char2cells; | |
150 | mb_off2cells = dbcs_off2cells; | |
151 | mb_ptr2char = dbcs_ptr2char; | |
152 | *************** | |
153 | *** 628,636 **** | |
154 | --- 635,645 ---- | |
155 | else | |
156 | { | |
157 | mb_ptr2len = latin_ptr2len; | |
158 | + mb_ptr2len_len = latin_ptr2len_len; | |
159 | mb_char2len = latin_char2len; | |
160 | mb_char2bytes = latin_char2bytes; | |
161 | mb_ptr2cells = latin_ptr2cells; | |
162 | + mb_ptr2cells_len = latin_ptr2cells_len; | |
163 | mb_char2cells = latin_char2cells; | |
164 | mb_off2cells = latin_off2cells; | |
165 | mb_ptr2char = latin_ptr2char; | |
166 | *************** | |
167 | *** 1069,1075 **** | |
168 | * Get byte length of character at "*p" but stop at a NUL. | |
169 | * For UTF-8 this includes following composing characters. | |
170 | * Returns 0 when *p is NUL. | |
171 | - * | |
172 | */ | |
173 | int | |
174 | latin_ptr2len(p) | |
175 | --- 1078,1083 ---- | |
176 | *************** | |
177 | *** 1091,1096 **** | |
178 | --- 1099,1138 ---- | |
179 | return len; | |
180 | } | |
181 | ||
182 | + /* | |
183 | + * mb_ptr2len_len() function pointer. | |
184 | + * Like mb_ptr2len(), but limit to read "size" bytes. | |
185 | + * Returns 0 for an empty string. | |
186 | + * Returns 1 for an illegal char or an incomplete byte sequence. | |
187 | + */ | |
188 | + int | |
189 | + latin_ptr2len_len(p, size) | |
190 | + char_u *p; | |
191 | + int size; | |
192 | + { | |
193 | + if (size < 1 || *p == NUL) | |
194 | + return 0; | |
195 | + return 1; | |
196 | + } | |
197 | + | |
198 | + static int | |
199 | + dbcs_ptr2len_len(p, size) | |
200 | + char_u *p; | |
201 | + int size; | |
202 | + { | |
203 | + int len; | |
204 | + | |
205 | + if (size < 1 || *p == NUL) | |
206 | + return 0; | |
207 | + if (size == 1) | |
208 | + return 1; | |
209 | + /* Check that second byte is not missing. */ | |
210 | + len = MB_BYTE2LEN(*p); | |
211 | + if (len == 2 && p[1] == NUL) | |
212 | + len = 1; | |
213 | + return len; | |
214 | + } | |
215 | + | |
216 | struct interval | |
217 | { | |
218 | unsigned short first; | |
219 | *************** | |
220 | *** 1287,1292 **** | |
221 | --- 1329,1383 ---- | |
222 | } | |
223 | ||
224 | /* | |
225 | + * mb_ptr2cells_len() function pointer. | |
226 | + * Like mb_ptr2cells(), but limit string length to "size". | |
227 | + * For an empty string or truncated character returns 1. | |
228 | + */ | |
229 | + int | |
230 | + latin_ptr2cells_len(p, size) | |
231 | + char_u *p UNUSED; | |
232 | + int size UNUSED; | |
233 | + { | |
234 | + return 1; | |
235 | + } | |
236 | + | |
237 | + static int | |
238 | + utf_ptr2cells_len(p, size) | |
239 | + char_u *p; | |
240 | + int size; | |
241 | + { | |
242 | + int c; | |
243 | + | |
244 | + /* Need to convert to a wide character. */ | |
245 | + if (size > 0 && *p >= 0x80) | |
246 | + { | |
247 | + if (utf_ptr2len_len(p, size) < utf8len_tab[*p]) | |
248 | + return 1; | |
249 | + c = utf_ptr2char(p); | |
250 | + /* An illegal byte is displayed as <xx>. */ | |
251 | + if (utf_ptr2len(p) == 1 || c == NUL) | |
252 | + return 4; | |
253 | + /* If the char is ASCII it must be an overlong sequence. */ | |
254 | + if (c < 0x80) | |
255 | + return char2cells(c); | |
256 | + return utf_char2cells(c); | |
257 | + } | |
258 | + return 1; | |
259 | + } | |
260 | + | |
261 | + static int | |
262 | + dbcs_ptr2cells_len(p, size) | |
263 | + char_u *p; | |
264 | + int size; | |
265 | + { | |
266 | + /* Number of cells is equal to number of bytes, except for euc-jp when | |
267 | + * the first byte is 0x8e. */ | |
268 | + if (size <= 1 || (enc_dbcs == DBCS_JPNU && *p == 0x8e)) | |
269 | + return 1; | |
270 | + return MB_BYTE2LEN(*p); | |
271 | + } | |
272 | + | |
273 | + /* | |
274 | * mb_char2cells() function pointer. | |
275 | * Return the number of display cells character "c" occupies. | |
276 | * Only takes care of multi-byte chars, not "^C" and such. | |
277 | *************** | |
278 | *** 1716,1721 **** | |
279 | --- 1807,1813 ---- | |
280 | /* | |
281 | * Return the number of bytes the UTF-8 encoding of the character at "p[size]" | |
282 | * takes. This includes following composing characters. | |
283 | + * Returns 0 for an empty string. | |
284 | * Returns 1 for an illegal char or an incomplete byte sequence. | |
285 | */ | |
286 | int | |
287 | *************** | |
288 | *** 1728,1734 **** | |
289 | int prevlen; | |
290 | #endif | |
291 | ||
292 | ! if (*p == NUL) | |
293 | return 0; | |
294 | if (p[0] < 0x80 && (size == 1 || p[1] < 0x80)) /* be quick for ASCII */ | |
295 | return 1; | |
296 | --- 1820,1826 ---- | |
297 | int prevlen; | |
298 | #endif | |
299 | ||
300 | ! if (size < 1 || *p == NUL) | |
301 | return 0; | |
302 | if (p[0] < 0x80 && (size == 1 || p[1] < 0x80)) /* be quick for ASCII */ | |
303 | return 1; | |
304 | *** ../vim-7.2.199/src/proto/mbyte.pro 2008-07-13 19:34:19.000000000 +0200 | |
305 | --- src/proto/mbyte.pro 2009-06-16 14:58:39.000000000 +0200 | |
306 | *************** | |
307 | *** 7,16 **** | |
308 | --- 7,18 ---- | |
309 | int latin_char2len __ARGS((int c)); | |
310 | int latin_char2bytes __ARGS((int c, char_u *buf)); | |
311 | int latin_ptr2len __ARGS((char_u *p)); | |
312 | + int latin_ptr2len_len __ARGS((char_u *p, int size)); | |
313 | int utf_char2cells __ARGS((int c)); | |
314 | int latin_ptr2cells __ARGS((char_u *p)); | |
315 | int utf_ptr2cells __ARGS((char_u *p)); | |
316 | int dbcs_ptr2cells __ARGS((char_u *p)); | |
317 | + int latin_ptr2cells_len __ARGS((char_u *p, int size)); | |
318 | int latin_char2cells __ARGS((int c)); | |
319 | int latin_off2cells __ARGS((unsigned off, unsigned max_off)); | |
320 | int dbcs_off2cells __ARGS((unsigned off, unsigned max_off)); | |
321 | *************** | |
322 | *** 85,90 **** | |
323 | --- 87,93 ---- | |
324 | int preedit_get_status __ARGS((void)); | |
325 | int im_is_preediting __ARGS((void)); | |
326 | int convert_setup __ARGS((vimconv_T *vcp, char_u *from, char_u *to)); | |
327 | + int convert_setup_ext __ARGS((vimconv_T *vcp, char_u *from, int from_unicode_is_utf8, char_u *to, int to_unicode_is_utf8)); | |
328 | int convert_input __ARGS((char_u *ptr, int len, int maxlen)); | |
329 | int convert_input_safe __ARGS((char_u *ptr, int len, int maxlen, char_u **restp, int *restlenp)); | |
330 | char_u *string_convert __ARGS((vimconv_T *vcp, char_u *ptr, int *lenp)); | |
331 | *** ../vim-7.2.199/src/version.c 2009-06-16 14:31:56.000000000 +0200 | |
332 | --- src/version.c 2009-06-16 14:37:38.000000000 +0200 | |
333 | *************** | |
334 | *** 678,679 **** | |
335 | --- 678,681 ---- | |
336 | { /* Add new patch number below this line */ | |
337 | + /**/ | |
338 | + 200, | |
339 | /**/ | |
340 | ||
341 | -- | |
342 | How To Keep A Healthy Level Of Insanity: | |
343 | 12. Sing along at the opera. | |
344 | ||
345 | /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ | |
346 | /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ | |
347 | \\\ download, build and distribute -- http://www.A-A-P.org /// | |
348 | \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |