Commit cc0af24a authored by Pekka Pessi's avatar Pekka Pessi

Use memmem() only indirectly through bm_memmem()

parent 6e6b8873
......@@ -40,6 +40,7 @@
#include <sofia-sip/su_alloc.h>
#include <sofia-sip/su_string.h>
#include <sofia-sip/su_bm.h>
#include "msg_internal.h"
#include "sofia-sip/msg.h"
......@@ -55,11 +56,6 @@
#include <errno.h>
#include <assert.h>
#if !HAVE_MEMMEM
void *memmem(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen);
#endif
/** Protocol version of MIME */
char const msg_mime_version_1_0[] = "MIME/1.0";
......@@ -330,7 +326,7 @@ msg_multipart_search_boundary(su_home_t *home, char const *p, size_t len)
}
/* Look for LF -- */
for (;(p = memmem(p, end - p, LF "--", 3)); p += 3) {
for (;(p = bm_memmem(p, end - p, LF "--", 3, NULL)); p += 3) {
len = end - p;
m = 3 + su_memspn(p + 3, len - 3, bchars, bchars_len);
if (m + 2 >= len)
......@@ -380,6 +376,7 @@ msg_multipart_t *msg_multipart_parse(su_home_t *home,
char *boundary, *p, *next, save;
char const *b, *end;
msg_param_t param;
bm_fwd_table_t *fwd = NULL;
p = pl->pl_data; len = pl->pl_len; end = p + len;
......@@ -398,16 +395,20 @@ msg_multipart_t *msg_multipart_parse(su_home_t *home,
m = strlen(boundary) - 2, blen = m - 1;
if (blen > 8 * sizeof (long))
fwd = bm_memmem_study(boundary + 1, blen);
/* Find first delimiter */
if (memcmp(boundary + 2, p, m - 2) == 0)
b = p, p = p + m - 2, len -= m - 2;
else if ((p = memmem(p, len, boundary + 1, m - 1))) {
else if ((p = bm_memmem(p, len, boundary + 1, blen, fwd))) {
if (p != pl->pl_data && p[-1] == '\r')
b = --p, p = p + m, len -= m;
else
b = p, p = p + m - 1, len -= m - 1;
}
else {
free(fwd);
su_home_deinit(msg_home(msg));
return NULL;
}
......@@ -424,7 +425,7 @@ msg_multipart_t *msg_multipart_parse(su_home_t *home,
if (len < blen)
break;
next = memmem(p, len, boundary + 1, m = blen);
next = bm_memmem(p, len, boundary + 1, m = blen, fwd);
if (!next)
break; /* error */
......@@ -463,6 +464,8 @@ msg_multipart_t *msg_multipart_parse(su_home_t *home,
b = next; p = next + m;
}
free(fwd), fwd = NULL;
if (!mp || !mp->mp_close_delim) {
su_home_deinit(msg_home(msg));
/* Delimiter error */
......
......@@ -105,6 +105,24 @@ bm_memmem_study(char const *needle, size_t nlen)
return fwd;
}
#if !HAVE_MEMMEM
/* Naive implementation of memmem() */
static void *
memmem(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen)
{
size_t i;
char const *hs = haystack;
for (i = 0; i <= haystacklen - needlelen; i++) {
if (memcmp(hs + i, needle, needlelen) == 0)
return (void *)(hs + i);
}
return NULL;
}
#endif
/** Search for a substring using Boyer-Moore algorithm.
* @ingroup su_bm
*/
......@@ -128,8 +146,12 @@ bm_memmem(char const *haystack, size_t hlen,
return NULL;
}
if (!fwd)
if (!fwd) {
if (nlen < 8 * sizeof (long)) /* Just guessing */
return memmem(haystack, hlen, needle, nlen);
fwd = bm_memmem_study0(needle, nlen, fwd0);
}
for (i = j = nlen - 1; i < hlen;) {
unsigned char h = haystack[i];
......
......@@ -36,6 +36,7 @@
#include "config.h"
#include <sofia-sip/su_string.h>
#include <sofia-sip/su_bm.h>
#include <stddef.h>
#include <stdlib.h>
......@@ -43,11 +44,6 @@
#include <stdio.h>
#include <assert.h>
#if !HAVE_MEMMEM
void *memmem(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen);
#endif
#include <string.h>
static int test_flags = 0;
......@@ -63,6 +59,7 @@ void usage(int exitcode)
exit(exitcode);
}
static int test_notfound(void);
static int test_pattern(void);
......@@ -75,29 +72,29 @@ static int test_notfound(void)
char const *a;
BEGIN();
TEST_P(memmem(haystack, 12, needle, 3), haystack + 2);
TEST_P(memmem(needle, 3, haystack, 12), NULL);
TEST_P(bm_memmem(haystack, 12, needle, 3, NULL), haystack + 2);
TEST_P(bm_memmem(needle, 3, haystack, 12, NULL), NULL);
#if HAVE_MEMMEM
if (memmem(haystack, 12, "", 0) == NULL) {
if (bm_memmem(haystack, 12, "", 0, NULL) == NULL) {
fprintf(stderr, "test_memmem.c: "
"*** WARNING: system memmem() fails with empty needle ***\n");
}
else
#endif
{
TEST_P(memmem(haystack, 12, "", 0), haystack);
TEST_P(memmem(haystack, 12, null, 0), haystack);
TEST_P(memmem(haystack, 0, "", 0), haystack);
TEST_P(memmem(haystack, 0, null, 0), haystack);
TEST_P(bm_memmem(haystack, 12, "", 0, NULL), haystack);
TEST_P(bm_memmem(haystack, 12, null, 0, NULL), haystack);
TEST_P(bm_memmem(haystack, 0, "", 0, NULL), haystack);
TEST_P(bm_memmem(haystack, 0, null, 0, NULL), haystack);
}
TEST_P(memmem(haystack + 2, 3, needle, 3), haystack + 2);
TEST_P(memmem(haystack + 2, 2, needle, 3), NULL);
TEST_P(bm_memmem(haystack + 2, 3, needle, 3, NULL), haystack + 2);
TEST_P(bm_memmem(haystack + 2, 2, needle, 3, NULL), NULL);
a = "a\0bc";
TEST_P(memmem(a, 4, "a\0bc", 4), a);
TEST_P(memmem(a, 4, "\0bc", 3), a + 1);
TEST_P(bm_memmem(a, 4, "a\0bc", 4, NULL), a);
TEST_P(bm_memmem(a, 4, "\0bc", 3, NULL), a + 1);
END();
}
......
......@@ -531,6 +531,7 @@ AC_CHECK_FUNCS([gettimeofday strerror random initstate tcsetattr flock \
poll epoll_create kqueue select if_nameindex \
signal alarm \
strnlen \
memmem \
getaddrinfo getnameinfo freeaddrinfo gai_strerror getifaddrs \
getline getdelim getpass])
# getline getdelim getpass are _GNU_SOURCE stuff
......@@ -549,7 +550,7 @@ if test $ac_cv_func_if_nameindex = yes ; then
[Define to 1 if you have if_nameindex().])
fi
SAC_REPLACE_FUNCS([memmem memccpy memspn memcspn strtoull \
SAC_REPLACE_FUNCS([memccpy memspn memcspn strtoull \
inet_ntop inet_pton poll])
if test $ac_cv_func_signal = yes ; then
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment