Kaynağa Gözat

Add a tor_memmem function

svn:r4452
Nick Mathewson 20 yıl önce
ebeveyn
işleme
5fee58adfb
3 değiştirilmiş dosya ile 39 ekleme ve 3 silme
  1. 1 2
      configure.in
  2. 35 1
      src/common/compat.c
  3. 3 0
      src/common/compat.h

+ 1 - 2
configure.in

@@ -297,12 +297,11 @@ dnl These headers are not essential
 
 AC_CHECK_HEADERS(stdint.h sys/types.h inttypes.h sys/param.h sys/wait.h sys/limits.h netinet/in.h arpa/inet.h machine/limits.h syslog.h sys/time.h sys/resource.h pthread.h stddef.h inttypes.h)
 
-AC_CHECK_FUNCS(gettimeofday ftime socketpair uname inet_aton strptime getrlimit setrlimit strlcat strlcpy strtoull getpwnam ftello pthread_create getaddrinfo localtime_r gmtime_r event_get_version event_get_method event_set_log_callback)
+AC_CHECK_FUNCS(gettimeofday ftime socketpair uname inet_aton strptime getrlimit setrlimit strlcat strlcpy strtoull getpwnam ftello pthread_create getaddrinfo localtime_r gmtime_r event_get_version event_get_method event_set_log_callback memmem)
 AC_FUNC_FSEEKO
 
 AC_CHECK_MEMBERS([struct timeval.tv_sec])
 
-
 dnl In case we aren't given a working stdint.h, we'll need to grow our own.
 dnl Watch out.
 

+ 35 - 1
src/common/compat.c

@@ -13,7 +13,9 @@ const char compat_c_id[] = "$Id$";
  * the platform.
  **/
 
-/* This is required on rh7 to make strptime not complain. */
+/* This is required on rh7 to make strptime not complain.
+ * We also need it to make memmem get defined (where available)
+ */
 #define _GNU_SOURCE
 
 #include "orconfig.h"
@@ -134,6 +136,38 @@ tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
   return r;
 }
 
+/** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at
+ * <b>needle</b>, return a pointer to the first occurence of the needle
+ * within the haystack, or NULL if there is no such occurrence.
+ *
+ * Requires that nlen be greater than zero.
+ */
+const void *
+tor_memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen)
+{
+#if defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2)
+  tor_assert(nlen);
+  return memmem(haystack, hlen, needle, nlen);
+#else
+  /* This isn't as fast as the GLIBC implementation, but it doesn't need to be. */
+  const void *p, *end;
+  char first;
+  tor_assert(nlen);
+
+  p = haystack;
+  end = haystack + hlen;
+  first = *(const char*)needle;
+  while ((p = memchr(p, first, end-p))) {
+    if (end-p >= nlen)
+      return NULL;
+    if (!memcmp(p, needle, nlen))
+      return p;
+    ++p;
+  }
+  return NULL;
+#endif
+}
+
 /** Take a filename and return a pointer to its final element.  This
  * function is called on __FILE__ to fix a MSVC nit where __FILE__
  * contains the full path to the file.  This is bad, because it

+ 3 - 0
src/common/compat.h

@@ -87,6 +87,9 @@ int tor_snprintf(char *str, size_t size, const char *format, ...)
      CHECK_PRINTF(3,4);
 int tor_vsnprintf(char *str, size_t size, const char *format, va_list args);
 
+const void *tor_memmem(const void *haystack, size_t hlen, const void *needle,
+                       size_t nlen);
+
 #define TOR_ISAPLHA(c)   isalpha((int)(unsigned char)(c))
 #define TOR_ISALNUM(c)   isalnum((int)(unsigned char)(c))
 #define TOR_ISSPACE(c)   isspace((int)(unsigned char)(c))