diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-11-11 14:45:04 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-11-11 14:45:04 -0200 |
| commit | a6755e2f1a6b9993cfd9e94c4165c76adafbdc31 (patch) | |
| tree | 697d7f5ab62b5650d3afc33a1985952e3fd2ca33 | |
| parent | a4628a02cfb11ac01a8496fb1359a4d66c49f887 (diff) | |
| download | lua-a6755e2f1a6b9993cfd9e94c4165c76adafbdc31.tar.gz lua-a6755e2f1a6b9993cfd9e94c4165c76adafbdc31.tar.bz2 lua-a6755e2f1a6b9993cfd9e94c4165c76adafbdc31.zip | |
BUG: `strfind' does not handle \0 in plain search.
| -rw-r--r-- | bugs | 5 | ||||
| -rw-r--r-- | lstrlib.c | 41 |
2 files changed, 36 insertions, 10 deletions
| @@ -122,3 +122,8 @@ could realloc f->consts. | |||
| 122 | Wed Sep 8 17:41:54 EST 1999 | 122 | Wed 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 | ||
| 127 | Thu Nov 11 14:36:30 EDT 1999 | ||
| 128 | >> `strfind' does not handle \0 in plain search. | ||
| 129 | (by Jon Kleiser; since 3.1) | ||
| @@ -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 | |||
| 377 | static 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 | |||
| 376 | static void str_find (void) { | 397 | static 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 | ||
