/* CC0 (Public domain) - see LICENSE file for details */ #include "config.h" #include #include #include "mem.h" #if !HAVE_MEMMEM void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { const char *p; if (needlelen > haystacklen) return NULL; p = haystack; for (p = haystack; (p + needlelen) <= ((const char *)haystack + haystacklen); p++) if (memcmp(p, needle, needlelen) == 0) return (void *)p; return NULL; } #endif #if !HAVE_MEMRCHR void *memrchr(const void *s, int c, size_t n) { unsigned char *p = (unsigned char *)s; while (n) { if (p[n-1] == c) return p + n - 1; n--; } return NULL; } #endif void *mempbrkm(const void *data_, size_t len, const void *accept_, size_t accept_len) { const char *data = data_, *accept = accept_; size_t i, j; for (i = 0; i < len; i++) for (j = 0; j < accept_len; j++) if (accept[j] == data[i]) return (void *)&data[i]; return NULL; } void *memcchr(void const *data, int c, size_t data_len) { char const *p = data; size_t i; for (i = 0; i < data_len; i++) if (p[i] != c) return (void *)&p[i]; return NULL; } #define MEMSWAP_TMP_SIZE 256 void memswap(void *a, void *b, size_t n) { char *ap = a; char *bp = b; char tmp[MEMSWAP_TMP_SIZE]; assert(!memoverlaps(a, n, b, n)); while (n) { size_t m = n > MEMSWAP_TMP_SIZE ? MEMSWAP_TMP_SIZE : n; memcpy(tmp, bp, m); memcpy(bp, ap, m); memcpy(ap, tmp, m); ap += m; bp += m; n -= m; } } bool memeqzero(const void *data, size_t length) { const unsigned char *p = data; size_t len; /* Check first 16 bytes manually */ for (len = 0; len < 16; len++) { if (!length) return true; if (*p) return false; p++; length--; } /* Now we know that's zero, memcmp with self. */ return memcmp(data, p, length) == 0; } void memtaint(void *data, size_t len) { /* Using 16 bytes is a bit quicker than 4 */ const unsigned tainter[] = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }; char *p = data; while (len >= sizeof(tainter)) { memcpy(p, tainter, sizeof(tainter)); p += sizeof(tainter); len -= sizeof(tainter); } memcpy(p, tainter, len); #if HAVE_VALGRIND_MEMCHECK_H VALGRIND_MAKE_MEM_UNDEFINED(data, len); #endif }