aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-01-04 10:53:24 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-01-04 10:53:24 -0200
commitb94110a68f0ca5740b5e09c04a8049fd451a2b7a (patch)
tree59a27795c68cc090e1cdd8486d6b3af22b61e0e6
parent827846804196b1779a61ffdc75d0aeb157f8465d (diff)
downloadlua-b94110a68f0ca5740b5e09c04a8049fd451a2b7a.tar.gz
lua-b94110a68f0ca5740b5e09c04a8049fd451a2b7a.tar.bz2
lua-b94110a68f0ca5740b5e09c04a8049fd451a2b7a.zip
bug: "format" does not check size of format item (such as "%00000...00000d").
-rw-r--r--bugs3
-rw-r--r--lstrlib.c72
2 files changed, 36 insertions, 39 deletions
diff --git a/bugs b/bugs
index c07d8a66..3a9bf65a 100644
--- a/bugs
+++ b/bugs
@@ -58,3 +58,6 @@ Fri Dec 18 11:22:55 EDT 1998
58>> "tonumber" goes crazy with negative numbers in other bases (not 10), 58>> "tonumber" goes crazy with negative numbers in other bases (not 10),
59because "strtol" returns long, not unsigned long. 59because "strtol" returns long, not unsigned long.
60 60
61** lstrlib.c
62Mon Jan 4 10:41:40 EDT 1999
63>> "format" does not check size of format item (such as "%00000...00000d").
diff --git a/lstrlib.c b/lstrlib.c
index e1eac354..719b7823 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.21 1998/12/01 18:41:25 roberto Exp roberto $ 2** $Id: lstrlib.c,v 1.22 1998/12/28 13:44:54 roberto Exp $
3** Standard library for strings and pattern-matching 3** Standard library for strings and pattern-matching
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -67,8 +67,7 @@ static void str_lower (void) {
67} 67}
68 68
69 69
70static void str_upper (void) 70static void str_upper (void) {
71{
72 long l; 71 long l;
73 int i; 72 int i;
74 char *s = luaL_check_lstr(1, &l); 73 char *s = luaL_check_lstr(1, &l);
@@ -90,8 +89,7 @@ static void str_rep (void)
90} 89}
91 90
92 91
93static void str_byte (void) 92static void str_byte (void) {
94{
95 long l; 93 long l;
96 char *s = luaL_check_lstr(1, &l); 94 char *s = luaL_check_lstr(1, &l);
97 long pos = posrelat(luaL_opt_long(2, 1), l); 95 long pos = posrelat(luaL_opt_long(2, 1), l);
@@ -99,6 +97,7 @@ static void str_byte (void)
99 lua_pushnumber((unsigned char)s[pos-1]); 97 lua_pushnumber((unsigned char)s[pos-1]);
100} 98}
101 99
100
102static void str_char (void) { 101static void str_char (void) {
103 int i = 0; 102 int i = 0;
104 luaL_resetbuffer(); 103 luaL_resetbuffer();
@@ -111,8 +110,9 @@ static void str_char (void) {
111} 110}
112 111
113 112
113
114/* 114/*
115** ======================================================= 115** {======================================================
116** PATTERN MATCHING 116** PATTERN MATCHING
117** ======================================================= 117** =======================================================
118*/ 118*/
@@ -120,8 +120,8 @@ static void str_char (void) {
120#define MAX_CAPT 9 120#define MAX_CAPT 9
121 121
122struct Capture { 122struct Capture {
123 int level; /* total number of captures (finished or unfinished) */
124 char *src_end; /* end ('\0') of source string */ 123 char *src_end; /* end ('\0') of source string */
124 int level; /* total number of captures (finished or unfinished) */
125 struct { 125 struct {
126 char *init; 126 char *init;
127 int len; /* -1 signals unfinished capture */ 127 int len; /* -1 signals unfinished capture */
@@ -133,8 +133,7 @@ struct Capture {
133#define SPECIALS "^$*?.([%-" 133#define SPECIALS "^$*?.([%-"
134 134
135 135
136static void push_captures (struct Capture *cap) 136static void push_captures (struct Capture *cap) {
137{
138 int i; 137 int i;
139 for (i=0; i<cap->level; i++) { 138 for (i=0; i<cap->level; i++) {
140 int l = cap->capture[i].len; 139 int l = cap->capture[i].len;
@@ -144,8 +143,7 @@ static void push_captures (struct Capture *cap)
144} 143}
145 144
146 145
147static int check_cap (int l, struct Capture *cap) 146static int check_cap (int l, struct Capture *cap) {
148{
149 l -= '1'; 147 l -= '1';
150 if (!(0 <= l && l < cap->level && cap->capture[l].len != -1)) 148 if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
151 lua_error("invalid capture index"); 149 lua_error("invalid capture index");
@@ -153,8 +151,7 @@ static int check_cap (int l, struct Capture *cap)
153} 151}
154 152
155 153
156static int capture_to_close (struct Capture *cap) 154static int capture_to_close (struct Capture *cap) {
157{
158 int level = cap->level; 155 int level = cap->level;
159 for (level--; level>=0; level--) 156 for (level--; level>=0; level--)
160 if (cap->capture[level].len == -1) return level; 157 if (cap->capture[level].len == -1) return level;
@@ -163,14 +160,12 @@ static int capture_to_close (struct Capture *cap)
163} 160}
164 161
165 162
166static char *bracket_end (char *p) 163static char *bracket_end (char *p) {
167{
168 return (*p == 0) ? NULL : strchr((*p=='^') ? p+2 : p+1, ']'); 164 return (*p == 0) ? NULL : strchr((*p=='^') ? p+2 : p+1, ']');
169} 165}
170 166
171 167
172static int matchclass (int c, int cl) 168static int matchclass (int c, int cl) {
173{
174 int res; 169 int res;
175 switch (tolower(cl)) { 170 switch (tolower(cl)) {
176 case 'a' : res = isalpha(c); break; 171 case 'a' : res = isalpha(c); break;
@@ -181,15 +176,15 @@ static int matchclass (int c, int cl)
181 case 's' : res = isspace(c); break; 176 case 's' : res = isspace(c); break;
182 case 'u' : res = isupper(c); break; 177 case 'u' : res = isupper(c); break;
183 case 'w' : res = isalnum(c); break; 178 case 'w' : res = isalnum(c); break;
179 case 'x' : res = isxdigit(c); break;
184 case 'z' : res = (c == '\0'); break; 180 case 'z' : res = (c == '\0'); break;
185 default: return (cl == c); 181 default: return (cl == c);
186 } 182 }
187 return (islower((unsigned char)cl) ? res : !res); 183 return (islower(cl) ? res : !res);
188} 184}
189 185
190 186
191int luaI_singlematch (int c, char *p, char **ep) 187int luaI_singlematch (int c, char *p, char **ep) {
192{
193 switch (*p) { 188 switch (*p) {
194 case '.': /* matches any char */ 189 case '.': /* matches any char */
195 *ep = p+1; 190 *ep = p+1;
@@ -228,8 +223,7 @@ int luaI_singlematch (int c, char *p, char **ep)
228} 223}
229 224
230 225
231static char *matchbalance (char *s, int b, int e, struct Capture *cap) 226static char *matchbalance (char *s, int b, int e, struct Capture *cap) {
232{
233 if (*s != b) return NULL; 227 if (*s != b) return NULL;
234 else { 228 else {
235 int cont = 1; 229 int cont = 1;
@@ -244,8 +238,7 @@ static char *matchbalance (char *s, int b, int e, struct Capture *cap)
244} 238}
245 239
246 240
247static char *matchitem (char *s, char *p, struct Capture *cap, char **ep) 241static char *matchitem (char *s, char *p, struct Capture *cap, char **ep) {
248{
249 if (*p == ESC) { 242 if (*p == ESC) {
250 p++; 243 p++;
251 if (isdigit((unsigned char)*p)) { /* capture */ 244 if (isdigit((unsigned char)*p)) { /* capture */
@@ -265,14 +258,13 @@ static char *matchitem (char *s, char *p, struct Capture *cap, char **ep)
265 } 258 }
266 else p--; /* and go through */ 259 else p--; /* and go through */
267 } 260 }
268 /* "luaI_singlematch" sets "ep" (so must be called even when *s == 0) */ 261 /* "luaI_singlematch" sets "ep" (so must be called even at the end of "s" */
269 return (luaI_singlematch((unsigned char)*s, p, ep) && s<cap->src_end) ? 262 return (luaI_singlematch((unsigned char)*s, p, ep) && s<cap->src_end) ?
270 s+1 : NULL; 263 s+1 : NULL;
271} 264}
272 265
273 266
274static char *match (char *s, char *p, struct Capture *cap) 267static char *match (char *s, char *p, struct Capture *cap) {
275{
276 init: /* using goto's to optimize tail recursion */ 268 init: /* using goto's to optimize tail recursion */
277 switch (*p) { 269 switch (*p) {
278 case '(': { /* start capture */ 270 case '(': { /* start capture */
@@ -298,7 +290,7 @@ static char *match (char *s, char *p, struct Capture *cap)
298 return s; 290 return s;
299 /* else go through */ 291 /* else go through */
300 default: { /* it is a pattern item */ 292 default: { /* it is a pattern item */
301 char *ep; /* get what is next */ 293 char *ep; /* will point to what is next */
302 char *s1 = matchitem(s, p, cap, &ep); 294 char *s1 = matchitem(s, p, cap, &ep);
303 switch (*ep) { 295 switch (*ep) {
304 case '*': { /* repetition */ 296 case '*': { /* repetition */
@@ -333,8 +325,7 @@ static char *match (char *s, char *p, struct Capture *cap)
333} 325}
334 326
335 327
336static void str_find (void) 328static void str_find (void) {
337{
338 long l; 329 long l;
339 char *s = luaL_check_lstr(1, &l); 330 char *s = luaL_check_lstr(1, &l);
340 char *p = luaL_check_string(2); 331 char *p = luaL_check_string(2);
@@ -369,8 +360,7 @@ static void str_find (void)
369} 360}
370 361
371 362
372static void add_s (lua_Object newp, struct Capture *cap) 363static void add_s (lua_Object newp, struct Capture *cap) {
373{
374 if (lua_isstring(newp)) { 364 if (lua_isstring(newp)) {
375 char *news = lua_getstring(newp); 365 char *news = lua_getstring(newp);
376 int l = lua_strlen(newp); 366 int l = lua_strlen(newp);
@@ -412,8 +402,7 @@ static void add_s (lua_Object newp, struct Capture *cap)
412} 402}
413 403
414 404
415static void str_gsub (void) 405static void str_gsub (void) {
416{
417 long srcl; 406 long srcl;
418 char *src = luaL_check_lstr(1, &srcl); 407 char *src = luaL_check_lstr(1, &srcl);
419 char *p = luaL_check_string(2); 408 char *p = luaL_check_string(2);
@@ -446,6 +435,8 @@ static void str_gsub (void)
446 lua_pushnumber(n); /* number of substitutions */ 435 lua_pushnumber(n); /* number of substitutions */
447} 436}
448 437
438/* }====================================================== */
439
449 440
450static void luaI_addquoted (int arg) { 441static void luaI_addquoted (int arg) {
451 long l; 442 long l;
@@ -465,10 +456,10 @@ static void luaI_addquoted (int arg) {
465 luaL_addchar('"'); 456 luaL_addchar('"');
466} 457}
467 458
468#define MAX_FORMAT 200 459/* maximum size of each format specification (such as '%-099.99d') */
460#define MAX_FORMAT 20
469 461
470static void str_format (void) 462static void str_format (void) {
471{
472 int arg = 1; 463 int arg = 1;
473 char *strfrmt = luaL_check_string(arg); 464 char *strfrmt = luaL_check_string(arg);
474 struct Capture cap; 465 struct Capture cap;
@@ -491,11 +482,14 @@ static void str_format (void)
491 } 482 }
492 arg++; 483 arg++;
493 strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap); 484 strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
494 if (cap.capture[0].len > 2 || cap.capture[1].len > 2) /* < 100? */ 485 if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */
486 strfrmt-initf > MAX_FORMAT-2)
495 lua_error("invalid format (width or precision too long)"); 487 lua_error("invalid format (width or precision too long)");
496 strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */ 488 strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
497 form[strfrmt-initf+2] = 0; 489 form[strfrmt-initf+2] = 0;
498 buff = luaL_openspace(1000); /* to store the formatted value */ 490 /* to store the formatted value
491 (450 > size of format('%99.99f', -1e308) */
492 buff = luaL_openspace(450);
499 switch (*strfrmt++) { 493 switch (*strfrmt++) {
500 case 'q': 494 case 'q':
501 luaI_addquoted(arg); 495 luaI_addquoted(arg);