-let's not introduce stdbool shortly before the release
[oweals/gnunet.git] / src / util / common_allocation.c
index 98c89d86a6b52ddf265694f12a27e1864ca43cbb..b5473671bb41c64e8de432aa1d43e1fa9609a948 100644 (file)
@@ -4,7 +4,7 @@
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
  * @brief wrapper around malloc/free
  * @author Christian Grothoff
  */
  * @brief wrapper around malloc/free
  * @author Christian Grothoff
  */
-
 #include "platform.h"
 #include "platform.h"
-#include "gnunet_common.h"
+#include "gnunet_util_lib.h"
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#if HAVE_MALLOC_MALLOC_H
+#include <malloc/malloc.h>
+#endif
+
+#define LOG(kind,...) GNUNET_log_from (kind, "util",__VA_ARGS__)
+
+#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
 
 #ifndef INT_MAX
 #define INT_MAX 0x7FFFFFFF
 
 #ifndef INT_MAX
 #define INT_MAX 0x7FFFFFFF
@@ -62,8 +71,8 @@ GNUNET_xmalloc_ (size_t size, const char *filename, int linenumber)
   ret = GNUNET_xmalloc_unchecked_ (size, filename, linenumber);
   if (ret == NULL)
   {
   ret = GNUNET_xmalloc_unchecked_ (size, filename, linenumber);
   if (ret == NULL)
   {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "malloc");
-    abort ();
+    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "malloc");
+    GNUNET_abort ();
   }
   return ret;
 }
   }
   return ret;
 }
@@ -98,8 +107,8 @@ GNUNET_xmemdup_ (const void *buf, size_t size, const char *filename,
   ret = malloc (size);
   if (ret == NULL)
   {
   ret = malloc (size);
   if (ret == NULL)
   {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "malloc");
-    abort ();
+    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "malloc");
+    GNUNET_abort ();
   }
 #ifdef W32_MEM_LIMIT
   *((size_t *) ret) = size;
   }
 #ifdef W32_MEM_LIMIT
   *((size_t *) ret) = size;
@@ -132,7 +141,6 @@ GNUNET_xmalloc_unchecked_ (size_t size, const char *filename, int linenumber)
     return NULL;
 #endif
 
     return NULL;
 #endif
 
-  GNUNET_assert_at (size < INT_MAX, filename, linenumber);
   result = malloc (size);
   if (result == NULL)
     return NULL;
   result = malloc (size);
   if (result == NULL)
     return NULL;
@@ -169,8 +177,8 @@ GNUNET_xrealloc_ (void *ptr, size_t n, const char *filename, int linenumber)
   ptr = realloc (ptr, n);
   if ((NULL == ptr) && (n > 0))
   {
   ptr = realloc (ptr, n);
   if ((NULL == ptr) && (n > 0))
   {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "realloc");
-    abort ();
+    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "realloc");
+    GNUNET_abort ();
   }
 #ifdef W32_MEM_LIMIT
   ptr = &((size_t *) ptr)[1];
   }
 #ifdef W32_MEM_LIMIT
   ptr = &((size_t *) ptr)[1];
@@ -179,6 +187,25 @@ GNUNET_xrealloc_ (void *ptr, size_t n, const char *filename, int linenumber)
 }
 
 
 }
 
 
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+#define BAADFOOD_STR "\x0D\xF0\xAD\xBA"
+#endif
+# if __BYTE_ORDER == __BIG_ENDIAN
+#define BAADFOOD_STR "\xBA\xAD\xF0\x0D"
+#endif
+
+#if WINDOWS
+#define M_SIZE(p) _msize (p)
+#endif
+#ifdef FREEBSD
+#include <malloc_np.h>
+#endif
+#if HAVE_MALLOC_USABLE_SIZE
+#define M_SIZE(p) malloc_usable_size (p)
+#elif HAVE_MALLOC_SIZE
+#define M_SIZE(p) malloc_size (p)
+#endif
+
 /**
  * Free memory. Merely a wrapper for the case that we
  * want to keep track of allocations.
 /**
  * Free memory. Merely a wrapper for the case that we
  * want to keep track of allocations.
@@ -194,6 +221,20 @@ GNUNET_xfree_ (void *ptr, const char *filename, int linenumber)
 #ifdef W32_MEM_LIMIT
   ptr = &((size_t *) ptr)[-1];
   mem_used -= *((size_t *) ptr);
 #ifdef W32_MEM_LIMIT
   ptr = &((size_t *) ptr)[-1];
   mem_used -= *((size_t *) ptr);
+#endif
+#if defined(M_SIZE)
+#if ENABLE_POISONING
+  {
+    const uint64_t baadfood = GNUNET_ntohll (0xBAADF00DBAADF00DLL);
+    uint64_t *base = ptr;
+    size_t s = M_SIZE (ptr);
+    size_t i;
+
+    for (i=0;i<s/8;i++)
+      base[i] = baadfood;
+    memcpy (&base[s/8], &baadfood, s % 8);
+  }
+#endif
 #endif
   free (ptr);
 }
 #endif
   free (ptr);
 }
@@ -218,6 +259,21 @@ GNUNET_xstrdup_ (const char *str, const char *filename, int linenumber)
 }
 
 
 }
 
 
+#if ! HAVE_STRNLEN
+static size_t
+strnlen (const char *s,
+        size_t n)
+{
+  const char *e;
+
+  e = memchr (s, '\0', n);
+  if (NULL == e)
+    return n;
+  return e - s;
+}
+#endif
+
+
 /**
  * Dup partially a string (same semantics as strndup).
  *
 /**
  * Dup partially a string (same semantics as strndup).
  *
@@ -233,11 +289,13 @@ GNUNET_xstrndup_ (const char *str, size_t len, const char *filename,
 {
   char *res;
 
 {
   char *res;
 
+  if (0 == len)
+    return GNUNET_strdup ("");
   GNUNET_assert_at (str != NULL, filename, linenumber);
   GNUNET_assert_at (str != NULL, filename, linenumber);
-  len = GNUNET_MIN (len, strlen (str));
+  len = strnlen (str, len);
   res = GNUNET_xmalloc_ (len + 1, filename, linenumber);
   memcpy (res, str, len);
   res = GNUNET_xmalloc_ (len + 1, filename, linenumber);
   memcpy (res, str, len);
-  res[len] = '\0';
+  /* res[len] = '\0'; 'malloc' zeros out anyway */
   return res;
 }
 
   return res;
 }