Safe allocation wrappers (#754)
Create allocation wrappers with a configurable OOM handler (defaults to abort()). See #752, #747
This commit is contained in:
parent
0501c623c9
commit
669ac9d0c8
@ -30,7 +30,8 @@ ADD_LIBRARY(hiredis SHARED
|
|||||||
net.c
|
net.c
|
||||||
read.c
|
read.c
|
||||||
sds.c
|
sds.c
|
||||||
sockcompat.c)
|
sockcompat.c
|
||||||
|
alloc.c)
|
||||||
|
|
||||||
SET_TARGET_PROPERTIES(hiredis
|
SET_TARGET_PROPERTIES(hiredis
|
||||||
PROPERTIES
|
PROPERTIES
|
||||||
|
19
Makefile
19
Makefile
@ -3,7 +3,7 @@
|
|||||||
# Copyright (C) 2010-2011 Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
# Copyright (C) 2010-2011 Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
||||||
# This file is released under the BSD license, see the COPYING file
|
# This file is released under the BSD license, see the COPYING file
|
||||||
|
|
||||||
OBJ=net.o hiredis.o sds.o async.o read.o sockcompat.o
|
OBJ=net.o hiredis.o sds.o async.o read.o sockcompat.o alloc.o
|
||||||
SSL_OBJ=ssl.o
|
SSL_OBJ=ssl.o
|
||||||
EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib
|
EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib
|
||||||
ifeq ($(USE_SSL),1)
|
ifeq ($(USE_SSL),1)
|
||||||
@ -95,15 +95,16 @@ all: $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(SSL_PKGCONFNAME)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
# Deps (use make dep to generate this)
|
# Deps (use make dep to generate this)
|
||||||
async.o: async.c fmacros.h async.h hiredis.h read.h sds.h net.h dict.c dict.h
|
async.o: async.c fmacros.h alloc.h async.h hiredis.h read.h sds.h net.h dict.c dict.h win32.h async_private.h
|
||||||
dict.o: dict.c fmacros.h dict.h
|
dict.o: dict.c fmacros.h alloc.h dict.h
|
||||||
hiredis.o: hiredis.c fmacros.h hiredis.h read.h sds.h net.h win32.h
|
hiredis.o: hiredis.c fmacros.h hiredis.h read.h sds.h alloc.h net.h async.h win32.h
|
||||||
net.o: net.c fmacros.h net.h hiredis.h read.h sds.h sockcompat.h win32.h
|
alloc.o: alloc.c alloc.h
|
||||||
read.o: read.c fmacros.h read.h sds.h
|
net.o: net.c fmacros.h net.h hiredis.h read.h sds.h alloc.h sockcompat.h win32.h
|
||||||
sds.o: sds.c sds.h
|
read.o: read.c fmacros.h read.h sds.h win32.h
|
||||||
|
sds.o: sds.c sds.h sdsalloc.h
|
||||||
sockcompat.o: sockcompat.c sockcompat.h
|
sockcompat.o: sockcompat.c sockcompat.h
|
||||||
ssl.o: ssl.c hiredis.h
|
ssl.o: ssl.c hiredis.h read.h sds.h alloc.h async.h async_private.h
|
||||||
test.o: test.c fmacros.h hiredis.h read.h sds.h
|
test.o: test.c fmacros.h hiredis.h read.h sds.h alloc.h net.h
|
||||||
|
|
||||||
$(DYLIBNAME): $(OBJ)
|
$(DYLIBNAME): $(OBJ)
|
||||||
$(DYLIB_MAKE_CMD) -o $(DYLIBNAME) $(OBJ) $(REAL_LDFLAGS)
|
$(DYLIB_MAKE_CMD) -o $(DYLIBNAME) $(OBJ) $(REAL_LDFLAGS)
|
||||||
|
@ -108,7 +108,7 @@ static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) {
|
|||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
|
|
||||||
/* Create container for context and r/w events */
|
/* Create container for context and r/w events */
|
||||||
e = (redisAeEvents*)malloc(sizeof(*e));
|
e = (redisAeEvents*)hi_malloc(sizeof(*e));
|
||||||
e->context = ac;
|
e->context = ac;
|
||||||
e->loop = loop;
|
e->loop = loop;
|
||||||
e->fd = c->fd;
|
e->fd = c->fd;
|
||||||
|
@ -55,7 +55,7 @@ static int redisIvykisAttach(redisAsyncContext *ac) {
|
|||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
|
|
||||||
/* Create container for context and r/w events */
|
/* Create container for context and r/w events */
|
||||||
e = (redisIvykisEvents*)malloc(sizeof(*e));
|
e = (redisIvykisEvents*)hi_malloc(sizeof(*e));
|
||||||
e->context = ac;
|
e->context = ac;
|
||||||
|
|
||||||
/* Register functions to start/stop listening for events */
|
/* Register functions to start/stop listening for events */
|
||||||
|
@ -119,7 +119,7 @@ static int redisLibevAttach(EV_P_ redisAsyncContext *ac) {
|
|||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
|
|
||||||
/* Create container for context and r/w events */
|
/* Create container for context and r/w events */
|
||||||
e = (redisLibevEvents*)malloc(sizeof(*e));
|
e = (redisLibevEvents*)hi_malloc(sizeof(*e));
|
||||||
e->context = ac;
|
e->context = ac;
|
||||||
#if EV_MULTIPLICITY
|
#if EV_MULTIPLICITY
|
||||||
e->loop = loop;
|
e->loop = loop;
|
||||||
|
@ -152,7 +152,7 @@ static int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) {
|
|||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
|
|
||||||
/* Create container for context and r/w events */
|
/* Create container for context and r/w events */
|
||||||
e = (redisLibeventEvents*)calloc(1, sizeof(*e));
|
e = (redisLibeventEvents*)hi_calloc(1, sizeof(*e));
|
||||||
e->context = ac;
|
e->context = ac;
|
||||||
|
|
||||||
/* Register functions to start/stop listening for events */
|
/* Register functions to start/stop listening for events */
|
||||||
|
65
alloc.c
Normal file
65
alloc.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Michael Grunder <michael dot grunder at gmail dot com>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of Redis nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "fmacros.h"
|
||||||
|
#include "alloc.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void *hi_malloc(size_t size) {
|
||||||
|
void *ptr = malloc(size);
|
||||||
|
if (ptr == NULL)
|
||||||
|
HIREDIS_OOM_HANDLER;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *hi_calloc(size_t nmemb, size_t size) {
|
||||||
|
void *ptr = calloc(nmemb, size);
|
||||||
|
if (ptr == NULL)
|
||||||
|
HIREDIS_OOM_HANDLER;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *hi_realloc(void *ptr, size_t size) {
|
||||||
|
void *newptr = realloc(ptr, size);
|
||||||
|
if (newptr == NULL)
|
||||||
|
HIREDIS_OOM_HANDLER;
|
||||||
|
|
||||||
|
return newptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *hi_strdup(const char *str) {
|
||||||
|
char *newstr = strdup(str);
|
||||||
|
if (newstr == NULL)
|
||||||
|
HIREDIS_OOM_HANDLER;
|
||||||
|
|
||||||
|
return newstr;
|
||||||
|
}
|
44
alloc.h
Normal file
44
alloc.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Michael Grunder <michael dot grunder at gmail dot com>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of Redis nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HIREDIS_ALLOC_H
|
||||||
|
|
||||||
|
#include <stdlib.h> /* for size_t */
|
||||||
|
|
||||||
|
#ifndef HIREDIS_OOM_HANDLER
|
||||||
|
#define HIREDIS_OOM_HANDLER abort()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *hi_malloc(size_t size);
|
||||||
|
void *hi_calloc(size_t nmemb, size_t size);
|
||||||
|
void *hi_realloc(void *ptr, size_t size);
|
||||||
|
char *hi_strdup(const char *str);
|
||||||
|
|
||||||
|
#endif /* HIREDIS_ALLOC_H */
|
5
async.c
5
async.c
@ -30,6 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "fmacros.h"
|
#include "fmacros.h"
|
||||||
|
#include "alloc.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
@ -57,7 +58,7 @@ static unsigned int callbackHash(const void *key) {
|
|||||||
|
|
||||||
static void *callbackValDup(void *privdata, const void *src) {
|
static void *callbackValDup(void *privdata, const void *src) {
|
||||||
((void) privdata);
|
((void) privdata);
|
||||||
redisCallback *dup = malloc(sizeof(*dup));
|
redisCallback *dup = hi_malloc(sizeof(*dup));
|
||||||
memcpy(dup,src,sizeof(*dup));
|
memcpy(dup,src,sizeof(*dup));
|
||||||
return dup;
|
return dup;
|
||||||
}
|
}
|
||||||
@ -754,7 +755,7 @@ int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void
|
|||||||
|
|
||||||
void redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv) {
|
void redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv) {
|
||||||
if (!ac->c.timeout) {
|
if (!ac->c.timeout) {
|
||||||
ac->c.timeout = calloc(1, sizeof(tv));
|
ac->c.timeout = hi_calloc(1, sizeof(tv));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tv.tv_sec == ac->c.timeout->tv_sec &&
|
if (tv.tv_sec == ac->c.timeout->tv_sec &&
|
||||||
|
7
dict.c
7
dict.c
@ -34,6 +34,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "fmacros.h"
|
#include "fmacros.h"
|
||||||
|
#include "alloc.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
@ -71,7 +72,7 @@ static void _dictReset(dict *ht) {
|
|||||||
|
|
||||||
/* Create a new hash table */
|
/* Create a new hash table */
|
||||||
static dict *dictCreate(dictType *type, void *privDataPtr) {
|
static dict *dictCreate(dictType *type, void *privDataPtr) {
|
||||||
dict *ht = malloc(sizeof(*ht));
|
dict *ht = hi_malloc(sizeof(*ht));
|
||||||
_dictInit(ht,type,privDataPtr);
|
_dictInit(ht,type,privDataPtr);
|
||||||
return ht;
|
return ht;
|
||||||
}
|
}
|
||||||
@ -142,7 +143,7 @@ static int dictAdd(dict *ht, void *key, void *val) {
|
|||||||
return DICT_ERR;
|
return DICT_ERR;
|
||||||
|
|
||||||
/* Allocates the memory and stores key */
|
/* Allocates the memory and stores key */
|
||||||
entry = malloc(sizeof(*entry));
|
entry = hi_malloc(sizeof(*entry));
|
||||||
entry->next = ht->table[index];
|
entry->next = ht->table[index];
|
||||||
ht->table[index] = entry;
|
ht->table[index] = entry;
|
||||||
|
|
||||||
@ -256,7 +257,7 @@ static dictEntry *dictFind(dict *ht, const void *key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static dictIterator *dictGetIterator(dict *ht) {
|
static dictIterator *dictGetIterator(dict *ht) {
|
||||||
dictIterator *iter = malloc(sizeof(*iter));
|
dictIterator *iter = hi_malloc(sizeof(*iter));
|
||||||
|
|
||||||
iter->ht = ht;
|
iter->ht = ht;
|
||||||
iter->index = -1;
|
iter->index = -1;
|
||||||
|
@ -42,6 +42,7 @@ struct timeval; /* forward declaration */
|
|||||||
#endif
|
#endif
|
||||||
#include <stdint.h> /* uintXX_t, etc */
|
#include <stdint.h> /* uintXX_t, etc */
|
||||||
#include "sds.h" /* for sds */
|
#include "sds.h" /* for sds */
|
||||||
|
#include "alloc.h" /* for allocation wrappers */
|
||||||
|
|
||||||
#define HIREDIS_MAJOR 0
|
#define HIREDIS_MAJOR 0
|
||||||
#define HIREDIS_MINOR 14
|
#define HIREDIS_MINOR 14
|
||||||
|
14
net.c
14
net.c
@ -358,13 +358,13 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
|
|||||||
if (c->tcp.host != addr) {
|
if (c->tcp.host != addr) {
|
||||||
free(c->tcp.host);
|
free(c->tcp.host);
|
||||||
|
|
||||||
c->tcp.host = strdup(addr);
|
c->tcp.host = hi_strdup(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
if (c->timeout != timeout) {
|
if (c->timeout != timeout) {
|
||||||
if (c->timeout == NULL)
|
if (c->timeout == NULL)
|
||||||
c->timeout = malloc(sizeof(struct timeval));
|
c->timeout = hi_malloc(sizeof(struct timeval));
|
||||||
|
|
||||||
memcpy(c->timeout, timeout, sizeof(struct timeval));
|
memcpy(c->timeout, timeout, sizeof(struct timeval));
|
||||||
}
|
}
|
||||||
@ -383,7 +383,7 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
|
|||||||
c->tcp.source_addr = NULL;
|
c->tcp.source_addr = NULL;
|
||||||
} else if (c->tcp.source_addr != source_addr) {
|
} else if (c->tcp.source_addr != source_addr) {
|
||||||
free(c->tcp.source_addr);
|
free(c->tcp.source_addr);
|
||||||
c->tcp.source_addr = strdup(source_addr);
|
c->tcp.source_addr = hi_strdup(source_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(_port, 6, "%d", port);
|
snprintf(_port, 6, "%d", port);
|
||||||
@ -447,7 +447,7 @@ addrretry:
|
|||||||
|
|
||||||
/* For repeat connection */
|
/* For repeat connection */
|
||||||
free(c->saddr);
|
free(c->saddr);
|
||||||
c->saddr = malloc(p->ai_addrlen);
|
c->saddr = hi_malloc(p->ai_addrlen);
|
||||||
memcpy(c->saddr, p->ai_addr, p->ai_addrlen);
|
memcpy(c->saddr, p->ai_addr, p->ai_addrlen);
|
||||||
c->addrlen = p->ai_addrlen;
|
c->addrlen = p->ai_addrlen;
|
||||||
|
|
||||||
@ -526,12 +526,12 @@ int redisContextConnectUnix(redisContext *c, const char *path, const struct time
|
|||||||
|
|
||||||
c->connection_type = REDIS_CONN_UNIX;
|
c->connection_type = REDIS_CONN_UNIX;
|
||||||
if (c->unix_sock.path != path)
|
if (c->unix_sock.path != path)
|
||||||
c->unix_sock.path = strdup(path);
|
c->unix_sock.path = hi_strdup(path);
|
||||||
|
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
if (c->timeout != timeout) {
|
if (c->timeout != timeout) {
|
||||||
if (c->timeout == NULL)
|
if (c->timeout == NULL)
|
||||||
c->timeout = malloc(sizeof(struct timeval));
|
c->timeout = hi_malloc(sizeof(struct timeval));
|
||||||
|
|
||||||
memcpy(c->timeout, timeout, sizeof(struct timeval));
|
memcpy(c->timeout, timeout, sizeof(struct timeval));
|
||||||
}
|
}
|
||||||
@ -543,7 +543,7 @@ int redisContextConnectUnix(redisContext *c, const char *path, const struct time
|
|||||||
if (redisContextTimeoutMsec(c,&timeout_msec) != REDIS_OK)
|
if (redisContextTimeoutMsec(c,&timeout_msec) != REDIS_OK)
|
||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
|
|
||||||
sa = (struct sockaddr_un*)(c->saddr = malloc(sizeof(struct sockaddr_un)));
|
sa = (struct sockaddr_un*)(c->saddr = hi_malloc(sizeof(struct sockaddr_un)));
|
||||||
c->addrlen = sizeof(struct sockaddr_un);
|
c->addrlen = sizeof(struct sockaddr_un);
|
||||||
sa->sun_family = AF_UNIX;
|
sa->sun_family = AF_UNIX;
|
||||||
strncpy(sa->sun_path, path, sizeof(sa->sun_path) - 1);
|
strncpy(sa->sun_path, path, sizeof(sa->sun_path) - 1);
|
||||||
|
2
ssl.c
2
ssl.c
@ -151,7 +151,7 @@ static void initOpensslLocks(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nlocks = CRYPTO_num_locks();
|
nlocks = CRYPTO_num_locks();
|
||||||
ossl_locks = malloc(sizeof(*ossl_locks) * nlocks);
|
ossl_locks = hi_malloc(sizeof(*ossl_locks) * nlocks);
|
||||||
for (ii = 0; ii < nlocks; ii++) {
|
for (ii = 0; ii < nlocks; ii++) {
|
||||||
sslLockInit(ossl_locks + ii);
|
sslLockInit(ossl_locks + ii);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user