1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
To: vim-dev@vim.org
Subject: Patch 7.2.307
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------
Patch 7.2.307
Problem: Crash with a very long syntax match statement. (Guy Gur Ari)
Solution: When the offset does not fit in the two bytes available give an
error instead of continuing with invalid pointers.
Files: src/regexp.c
*** ../vim-7.2.306/src/regexp.c 2009-05-15 21:31:11.000000000 +0200
--- src/regexp.c 2009-11-25 18:13:03.000000000 +0100
***************
*** 583,588 ****
--- 583,589 ----
#endif
static char_u *regcode; /* Code-emit pointer, or JUST_CALC_SIZE */
static long regsize; /* Code size. */
+ static int reg_toolong; /* TRUE when offset out of range */
static char_u had_endbrace[NSUBEXP]; /* flags, TRUE if end of () found */
static unsigned regflags; /* RF_ flags for prog */
static long brace_min[10]; /* Minimums for complex brace repeats */
***************
*** 1028,1036 ****
regcomp_start(expr, re_flags);
regcode = r->program;
regc(REGMAGIC);
! if (reg(REG_NOPAREN, &flags) == NULL)
{
vim_free(r);
return NULL;
}
--- 1029,1039 ----
regcomp_start(expr, re_flags);
regcode = r->program;
regc(REGMAGIC);
! if (reg(REG_NOPAREN, &flags) == NULL || reg_toolong)
{
vim_free(r);
+ if (reg_toolong)
+ EMSG_RET_NULL(_("E339: Pattern too long"));
return NULL;
}
***************
*** 1141,1146 ****
--- 1144,1150 ----
re_has_z = 0;
#endif
regsize = 0L;
+ reg_toolong = FALSE;
regflags = 0;
#if defined(FEAT_SYN_HL) || defined(PROTO)
had_eol = FALSE;
***************
*** 1228,1234 ****
{
skipchr();
br = regbranch(&flags);
! if (br == NULL)
return NULL;
regtail(ret, br); /* BRANCH -> BRANCH. */
if (!(flags & HASWIDTH))
--- 1232,1238 ----
{
skipchr();
br = regbranch(&flags);
! if (br == NULL || reg_toolong)
return NULL;
regtail(ret, br); /* BRANCH -> BRANCH. */
if (!(flags & HASWIDTH))
***************
*** 1313,1318 ****
--- 1317,1324 ----
break;
skipchr();
regtail(latest, regnode(END)); /* operand ends */
+ if (reg_toolong)
+ break;
reginsert(MATCH, latest);
chain = latest;
}
***************
*** 1382,1388 ****
break;
default:
latest = regpiece(&flags);
! if (latest == NULL)
return NULL;
*flagp |= flags & (HASWIDTH | HASNL | HASLOOKBH);
if (chain == NULL) /* First piece. */
--- 1388,1394 ----
break;
default:
latest = regpiece(&flags);
! if (latest == NULL || reg_toolong)
return NULL;
*flagp |= flags & (HASWIDTH | HASNL | HASLOOKBH);
if (chain == NULL) /* First piece. */
***************
*** 2540,2547 ****
offset = (int)(scan - val);
else
offset = (int)(val - scan);
! *(scan + 1) = (char_u) (((unsigned)offset >> 8) & 0377);
! *(scan + 2) = (char_u) (offset & 0377);
}
/*
--- 2546,2561 ----
offset = (int)(scan - val);
else
offset = (int)(val - scan);
! /* When the offset uses more than 16 bits it can no longer fit in the two
! * bytes avaliable. Use a global flag to avoid having to check return
! * values in too many places. */
! if (offset > 0xffff)
! reg_toolong = TRUE;
! else
! {
! *(scan + 1) = (char_u) (((unsigned)offset >> 8) & 0377);
! *(scan + 2) = (char_u) (offset & 0377);
! }
}
/*
***************
*** 5764,5769 ****
--- 5778,5785 ----
/*
* regnext - dig the "next" pointer out of a node
+ * Returns NULL when calculating size, when there is no next item and when
+ * there is an error.
*/
static char_u *
regnext(p)
***************
*** 5771,5777 ****
{
int offset;
! if (p == JUST_CALC_SIZE)
return NULL;
offset = NEXT(p);
--- 5787,5793 ----
{
int offset;
! if (p == JUST_CALC_SIZE || reg_toolong)
return NULL;
offset = NEXT(p);
*** ../vim-7.2.306/src/version.c 2009-11-25 17:15:16.000000000 +0100
--- src/version.c 2009-11-25 18:14:32.000000000 +0100
***************
*** 683,684 ****
--- 683,686 ----
{ /* Add new patch number below this line */
+ /**/
+ 307,
/**/
--
The fastest way to get an engineer to solve a problem is to declare that the
problem is unsolvable. No engineer can walk away from an unsolvable problem
until it's solved.
(Scott Adams - The Dilbert principle)
/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
|