aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-11-11 14:45:04 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-11-11 14:45:04 -0200
commita6755e2f1a6b9993cfd9e94c4165c76adafbdc31 (patch)
tree697d7f5ab62b5650d3afc33a1985952e3fd2ca33
parenta4628a02cfb11ac01a8496fb1359a4d66c49f887 (diff)
downloadlua-a6755e2f1a6b9993cfd9e94c4165c76adafbdc31.tar.gz
lua-a6755e2f1a6b9993cfd9e94c4165c76adafbdc31.tar.bz2
lua-a6755e2f1a6b9993cfd9e94c4165c76adafbdc31.zip
BUG: `strfind' does not handle \0 in plain search.
-rw-r--r--bugs5
-rw-r--r--lstrlib.c41
2 files changed, 36 insertions, 10 deletions
diff --git a/bugs b/bugs
index 114f3ef6..a402fcc4 100644
--- a/bugs
+++ b/bugs
@@ -122,3 +122,8 @@ could realloc f->consts.
122Wed Sep 8 17:41:54 EST 1999 122Wed Sep 8 17:41:54 EST 1999
123>> tonumber'e1' and tonumber(' ', x), for x!=10, gave 0 instead of nil. 123>> tonumber'e1' and tonumber(' ', x), for x!=10, gave 0 instead of nil.
124(since 3.1) 124(since 3.1)
125
126** lstrlib.c
127Thu Nov 11 14:36:30 EDT 1999
128>> `strfind' does not handle \0 in plain search.
129(by Jon Kleiser; since 3.1)
diff --git a/lstrlib.c b/lstrlib.c
index a388a0d9..27676543 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.34 1999/08/16 20:52:00 roberto Exp roberto $ 2** $Id: lstrlib.c,v 1.35 1999/10/25 13:35:44 roberto Exp roberto $
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*/
@@ -373,26 +373,47 @@ static const char *match (const char *s, const char *p, struct Capture *cap) {
373} 373}
374 374
375 375
376
377static const char *memfind (const char *s1, long l1, const char *s2, long l2) {
378 if (l2 == 0) return s1; /* empty strings are everywhere ;-) */
379 else {
380 const char *init; /* to search for a `*s2' inside `s1' */
381 l2--; /* 1st char will be checked by `memchr' */
382 l1 = l1-l2; /* `s2' cannot be found after that */
383 while (l1 > 0 && (init = memchr(s1, *s2, l1)) != NULL) {
384 init++; /* 1st char is already checked */
385 if (memcmp(init, s2+1, l2) == 0)
386 return init-1;
387 else { /* correct `l1' and `s1' to try again */
388 l1 -= init-s1;
389 s1 = init;
390 }
391 }
392 return NULL; /* not found */
393 }
394}
395
396
376static void str_find (void) { 397static void str_find (void) {
377 long l; 398 long l1, l2;
378 const char *s = luaL_check_lstr(1, &l); 399 const char *s = luaL_check_lstr(1, &l1);
379 const char *p = luaL_check_string(2); 400 const char *p = luaL_check_lstr(2, &l2);
380 long init = posrelat(luaL_opt_long(3, 1), l) - 1; 401 long init = posrelat(luaL_opt_long(3, 1), l1) - 1;
381 struct Capture cap; 402 struct Capture cap;
382 luaL_arg_check(0 <= init && init <= l, 3, "out of range"); 403 luaL_arg_check(0 <= init && init <= l1, 3, "out of range");
383 if (lua_getparam(4) != LUA_NOOBJECT || 404 if (lua_getparam(4) != LUA_NOOBJECT ||
384 strpbrk(p, SPECIALS) == NULL) { /* no special characters? */ 405 strpbrk(p, SPECIALS) == NULL) { /* no special characters? */
385 char *s2 = strstr(s+init, p); 406 const char *s2 = memfind(s+init, l1, p, l2);
386 if (s2) { 407 if (s2) {
387 lua_pushnumber(s2-s+1); 408 lua_pushnumber(s2-s+1);
388 lua_pushnumber(s2-s+strlen(p)); 409 lua_pushnumber(s2-s+l2);
389 return; 410 return;
390 } 411 }
391 } 412 }
392 else { 413 else {
393 int anchor = (*p == '^') ? (p++, 1) : 0; 414 int anchor = (*p == '^') ? (p++, 1) : 0;
394 const char *s1=s+init; 415 const char *s1=s+init;
395 cap.src_end = s+l; 416 cap.src_end = s+l1;
396 do { 417 do {
397 const char *res; 418 const char *res;
398 cap.level = 0; 419 cap.level = 0;
@@ -404,7 +425,7 @@ static void str_find (void) {
404 } 425 }
405 } while (s1++<cap.src_end && !anchor); 426 } while (s1++<cap.src_end && !anchor);
406 } 427 }
407 lua_pushnil(); /* if arrives here, it didn't find */ 428 lua_pushnil(); /* not found */
408} 429}
409 430
410 431