diff options
author | Liu Aleaxander <Aleaxander@gmail.com> | 2010-10-09 23:10:14 +0800 |
---|---|---|
committer | Liu Aleaxander <Aleaxander@gmail.com> | 2010-10-09 23:10:14 +0800 |
commit | a66a47e168804aa0a62a3a5810d7f8dd9b647dab (patch) | |
tree | 555d3a0394fdd2015bd04fe8d0b90108d6762db9 /com32/lib/memmem.c | |
parent | f2330884f94b131481042a5742711f518eac84cf (diff) | |
download | syslinux-a66a47e168804aa0a62a3a5810d7f8dd9b647dab.tar.gz syslinux-a66a47e168804aa0a62a3a5810d7f8dd9b647dab.tar.xz syslinux-a66a47e168804aa0a62a3a5810d7f8dd9b647dab.zip |
lib: Update memmem function
The current memem implementation can not handle the case that the length
of the third parameter(needle) is equal *ONE*. So that the current
strstr implemention doesn't work when the lenght of substring is ONE.
For example, strstr("linux", "l") it will return NULL instead of
"linux", which is not right.
This code is stolen from klibc ;)
Signed-off-by: Liu Aleaxander <Aleaxander@gmail.com>
Diffstat (limited to 'com32/lib/memmem.c')
-rw-r--r-- | com32/lib/memmem.c | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/com32/lib/memmem.c b/com32/lib/memmem.c index 8558a80d..7c42f1c3 100644 --- a/com32/lib/memmem.c +++ b/com32/lib/memmem.c @@ -18,26 +18,35 @@ void *memmem(const void *haystack, size_t n, const void *needle, size_t m) size_t j, k, l; - if (m > n) - return NULL; + if (m > n || !m || !n) + return NULL; - if (x[0] == x[1]) { - k = 2; - l = 1; - } else { - k = 1; - l = 2; - } + if (1 != m) { + if (x[0] == x[1]) { + k = 2; + l = 1; + } else { + k = 1; + l = 2; + } - j = 0; - while (j <= n - m) { - if (x[1] != y[j + 1]) { - j += k; - } else { - if (!memcmp(x + 2, y + j + 2, m - 2) && x[0] == y[j]) - return (void *)&y[j]; - j += l; - } + j = 0; + while (j <= n - m) { + if (x[1] != y[j + 1]) { + j += k; + } else { + if (!memcmp(x + 2, y + j + 2, m - 2) + && x[0] == y[j]) + return (void *)&y[j]; + j += l; + } + } + } else { + do { + if (*y == *x) + return (void *)y; + y++; + } while (--n); } return NULL; |