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 | ||