Skip to content

Commit

Permalink
Allow for realloc to be intercepted too
Browse files Browse the repository at this point in the history
Previous change to allow interposition of user-provided malloc/free
didn't cover use of realloc().
  • Loading branch information
daviddrysdale committed Nov 24, 2015
1 parent 2c5f595 commit 492a1cc
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 17 deletions.
3 changes: 2 additions & 1 deletion ares.h
Expand Up @@ -298,7 +298,8 @@ CARES_EXTERN int ares_library_init(int flags);

CARES_EXTERN int ares_library_init_mem(int flags,
void *(*amalloc)(size_t size),
void (*afree)(void *ptr));
void (*afree)(void *ptr),
void *(*arealloc)(void *ptr, size_t size));

CARES_EXTERN int ares_library_initialized(void);

Expand Down
2 changes: 1 addition & 1 deletion ares__read_line.c
Expand Up @@ -59,7 +59,7 @@ int ares__read_line(FILE *fp, char **buf, size_t *bufsize)
continue;

/* Allocate more space. */
newbuf = realloc(*buf, *bufsize * 2);
newbuf = ares_realloc(*buf, *bufsize * 2);
if (!newbuf)
{
ares_free(*buf);
Expand Down
12 changes: 6 additions & 6 deletions ares_init.c
Expand Up @@ -868,7 +868,7 @@ static int get_DNS_NetworkParams(char **outptr)
if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
goto done;

newfi = realloc(fi, size);
newfi = ares_realloc(fi, size);
if (!newfi)
goto done;

Expand Down Expand Up @@ -967,7 +967,7 @@ static int get_DNS_AdaptersAddresses(char **outptr)
{
if (Bufsz < ReqBufsz)
{
newipaa = realloc(ipaa, ReqBufsz);
newipaa = ares_realloc(ipaa, ReqBufsz);
if (!newipaa)
goto done;
Bufsz = ReqBufsz;
Expand Down Expand Up @@ -1399,7 +1399,7 @@ static int init_by_defaults(ares_channel channel)
char *p;
len *= 2;
lenv *= 2;
p = realloc(hostname, len);
p = ares_realloc(hostname, len);
if(!p) {
rc = ARES_ENOMEM;
goto error;
Expand Down Expand Up @@ -1561,8 +1561,8 @@ static int config_nameserver(struct server_state **servers, int *nservers,
continue;

/* Resize servers state array. */
newserv = realloc(*servers, (*nservers + 1) *
sizeof(struct server_state));
newserv = ares_realloc(*servers, (*nservers + 1) *
sizeof(struct server_state));
if (!newserv)
return ARES_ENOMEM;

Expand Down Expand Up @@ -1839,7 +1839,7 @@ static int sortlist_alloc(struct apattern **sortlist, int *nsort,
struct apattern *pat)
{
struct apattern *newsort;
newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
newsort = ares_realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
if (!newsort)
return 0;
newsort[*nsort] = *pat;
Expand Down
12 changes: 9 additions & 3 deletions ares_library_init.c
Expand Up @@ -36,6 +36,7 @@ static int ares_init_flags;

/* library-private global vars with visibility across the whole library */
void *(*ares_malloc)(size_t size) = malloc;
void *(*ares_realloc)(void *ptr, size_t size) = realloc;
void (*ares_free)(void *ptr) = free;

#ifdef USE_WINSOCK
Expand Down Expand Up @@ -125,10 +126,15 @@ int ares_library_init(int flags)

int ares_library_init_mem(int flags,
void *(*amalloc)(size_t size),
void (*afree)(void *ptr))
void (*afree)(void *ptr),
void *(*arealloc)(void *ptr, size_t size))
{
ares_malloc = amalloc;
ares_free = afree;
if (amalloc)
ares_malloc = amalloc;
if (arealloc)
ares_realloc = arealloc;
if (afree)
ares_free = afree;
return ares_library_init(flags);
}

Expand Down
2 changes: 1 addition & 1 deletion ares_parse_ptr_reply.c
Expand Up @@ -136,7 +136,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
if (aliascnt >= alias_alloc) {
char **ptr;
alias_alloc *= 2;
ptr = realloc(aliases, alias_alloc * sizeof(char *));
ptr = ares_realloc(aliases, alias_alloc * sizeof(char *));
if(!ptr) {
ares_free(rr_name);
status = ARES_ENOMEM;
Expand Down
1 change: 1 addition & 0 deletions ares_private.h
Expand Up @@ -306,6 +306,7 @@ struct ares_channeldata {

/* Memory management functions */
extern void *(*ares_malloc)(size_t size);
extern void *(*ares_realloc)(void *ptr, size_t size);
extern void (*ares_free)(void *ptr);

/* return true if now is exactly check time or later */
Expand Down
2 changes: 1 addition & 1 deletion ares_process.c
Expand Up @@ -570,7 +570,7 @@ static void process_answer(ares_channel channel, unsigned char *abuf,
query->tcpbuf[0] = (unsigned char)((qlen >> 8) & 0xff);
query->tcpbuf[1] = (unsigned char)(qlen & 0xff);
DNS_HEADER_SET_ARCOUNT(query->tcpbuf + 2, 0);
query->tcpbuf = realloc(query->tcpbuf, query->tcplen);
query->tcpbuf = ares_realloc(query->tcpbuf, query->tcplen);
ares__send_query(channel, query, now);
return;
}
Expand Down
3 changes: 2 additions & 1 deletion test/ares-test-init.cc
Expand Up @@ -125,7 +125,8 @@ TEST_F(LibraryTest, FailChannelInit) {
EXPECT_EQ(ARES_SUCCESS,
ares_library_init_mem(ARES_LIB_INIT_ALL,
&LibraryTest::amalloc,
&LibraryTest::afree));
&LibraryTest::afree,
&LibraryTest::arealloc));
SetAllocFail(1);
ares_channel channel = nullptr;
EXPECT_EQ(ARES_ENOMEM, ares_init(&channel));
Expand Down
20 changes: 18 additions & 2 deletions test/ares-test.cc
Expand Up @@ -74,22 +74,38 @@ void LibraryTest::ClearFails() {
size_fails_.clear();
}


// static
void* LibraryTest::amalloc(size_t size) {
bool LibraryTest::ShouldAllocFail(size_t size) {
bool fail = (fails_ & 0x01);
fails_ >>= 1;
if (size_fails_[size] > 0) {
size_fails_[size]--;
fail = true;
}
if (fail) {
return fail;
}

// static
void* LibraryTest::amalloc(size_t size) {
if (ShouldAllocFail(size)) {
if (verbose) std::cerr << "Failing malloc(" << size << ") request" << std::endl;
return nullptr;
} else {
return malloc(size);
}
}

// static
void* LibraryTest::arealloc(void *ptr, size_t size) {
if (ShouldAllocFail(size)) {
if (verbose) std::cerr << "Failing realloc(" << ptr << ", " << size << ") request" << std::endl;
return nullptr;
} else {
return realloc(ptr, size);
}
}

// static
void LibraryTest::afree(void *ptr) {
free(ptr);
Expand Down
5 changes: 4 additions & 1 deletion test/ares-test.h
Expand Up @@ -37,7 +37,8 @@ class LibraryTest : public ::testing::Test {
EXPECT_EQ(ARES_SUCCESS,
ares_library_init_mem(ARES_LIB_INIT_ALL,
&LibraryTest::amalloc,
&LibraryTest::afree));
&LibraryTest::afree,
&LibraryTest::arealloc));
}
~LibraryTest() {
ares_library_cleanup();
Expand All @@ -52,8 +53,10 @@ class LibraryTest : public ::testing::Test {
static void ClearFails();

static void *amalloc(size_t size);
static void* arealloc(void *ptr, size_t size);
static void afree(void *ptr);
private:
static bool ShouldAllocFail(size_t size);
static unsigned long fails_;
static std::map<size_t, int> size_fails_;
};
Expand Down

0 comments on commit 492a1cc

Please sign in to comment.