Permalink
Browse files

src: memory management using smart pointer

Introduced use of smart pointers instead of MallocedBuffer to manage
memory allocated in the cares library.

PR-URL: #23628
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
  • Loading branch information...
uttampawar authored and refack committed Oct 12, 2018
1 parent d8b6a1d commit acb363ffc40a0a76f7314385309a6d4ed78ef354
Showing with 54 additions and 55 deletions.
  1. +54 −55 src/cares_wrap.cc
@@ -1061,118 +1061,117 @@ int ParseSoaReply(Environment* env,
EscapableHandleScope handle_scope(env->isolate());
auto context = env->context();
/* Can't use ares_parse_soa_reply() here which can only parse single record */
unsigned int ancount = cares_get_16bit(buf + 6);
// Manage memory using standardard smart pointer std::unique_tr
struct AresDeleter {
void operator()(char* ptr) const noexcept { ares_free_string(ptr); }
};
using ares_unique_ptr = std::unique_ptr<char[], AresDeleter>;
// Can't use ares_parse_soa_reply() here which can only parse single record
const unsigned int ancount = cares_get_16bit(buf + 6);
unsigned char* ptr = buf + NS_HFIXEDSZ;
char* name;
char* rr_name;
char* name_temp;
long temp_len; // NOLINT(runtime/int)
int status = ares_expand_name(ptr, buf, len, &name, &temp_len);
int status = ares_expand_name(ptr, buf, len, &name_temp, &temp_len);
const ares_unique_ptr name(name_temp);
if (status != ARES_SUCCESS) {
/* returns EBADRESP in case of invalid input */
// returns EBADRESP in case of invalid input
return status == ARES_EBADNAME ? ARES_EBADRESP : status;
}
if (ptr + temp_len + NS_QFIXEDSZ > buf + len) {
free(name);
return ARES_EBADRESP;
}
ptr += temp_len + NS_QFIXEDSZ;
for (unsigned int i = 0; i < ancount; i++) {
status = ares_expand_name(ptr, buf, len, &rr_name, &temp_len);
char* rr_name_temp;
long rr_temp_len; // NOLINT(runtime/int)
int status2 = ares_expand_name(ptr, buf, len, &rr_name_temp, &rr_temp_len);
const ares_unique_ptr rr_name(rr_name_temp);
if (status != ARES_SUCCESS)
break;
if (status2 != ARES_SUCCESS)
return status2 == ARES_EBADNAME ? ARES_EBADRESP : status2;
ptr += temp_len;
ptr += rr_temp_len;
if (ptr + NS_RRFIXEDSZ > buf + len) {
free(rr_name);
status = ARES_EBADRESP;
break;
return ARES_EBADRESP;
}
const int rr_type = cares_get_16bit(ptr);
const int rr_len = cares_get_16bit(ptr + 8);
ptr += NS_RRFIXEDSZ;
/* only need SOA */
// only need SOA
if (rr_type == ns_t_soa) {
ares_soa_reply soa;
status = ares_expand_name(ptr, buf, len, &soa.nsname, &temp_len);
if (status != ARES_SUCCESS) {
free(rr_name);
break;
char* nsname_temp;
long nsname_temp_len; // NOLINT(runtime/int)
int status3 = ares_expand_name(ptr, buf, len,
&nsname_temp,
&nsname_temp_len);
const ares_unique_ptr nsname(nsname_temp);
if (status3 != ARES_SUCCESS) {
return status3 == ARES_EBADNAME ? ARES_EBADRESP : status3;
}
ptr += temp_len;
status = ares_expand_name(ptr, buf, len, &soa.hostmaster, &temp_len);
if (status != ARES_SUCCESS) {
free(rr_name);
free(soa.nsname);
break;
ptr += nsname_temp_len;
char* hostmaster_temp;
long hostmaster_temp_len; // NOLINT(runtime/int)
int status4 = ares_expand_name(ptr, buf, len,
&hostmaster_temp,
&hostmaster_temp_len);
const ares_unique_ptr hostmaster(hostmaster_temp);
if (status4 != ARES_SUCCESS) {
return status4 == ARES_EBADNAME ? ARES_EBADRESP : status4;
}
ptr += temp_len;
ptr += hostmaster_temp_len;
if (ptr + 5 * 4 > buf + len) {
free(rr_name);
free(soa.nsname);
free(soa.hostmaster);
status = ARES_EBADRESP;
break;
return ARES_EBADRESP;
}
soa.serial = cares_get_32bit(ptr + 0 * 4);
soa.refresh = cares_get_32bit(ptr + 1 * 4);
soa.retry = cares_get_32bit(ptr + 2 * 4);
soa.expire = cares_get_32bit(ptr + 3 * 4);
soa.minttl = cares_get_32bit(ptr + 4 * 4);
const unsigned int serial = cares_get_32bit(ptr + 0 * 4);
const unsigned int refresh = cares_get_32bit(ptr + 1 * 4);
const unsigned int retry = cares_get_32bit(ptr + 2 * 4);
const unsigned int expire = cares_get_32bit(ptr + 3 * 4);
const unsigned int minttl = cares_get_32bit(ptr + 4 * 4);
Local<Object> soa_record = Object::New(env->isolate());
soa_record->Set(context,
env->nsname_string(),
OneByteString(env->isolate(), soa.nsname)).FromJust();
OneByteString(env->isolate(), nsname.get())).FromJust();
soa_record->Set(context,
env->hostmaster_string(),
OneByteString(env->isolate(),
soa.hostmaster)).FromJust();
hostmaster.get())).FromJust();
soa_record->Set(context,
env->serial_string(),
Integer::New(env->isolate(), soa.serial)).FromJust();
Integer::New(env->isolate(), serial)).FromJust();
soa_record->Set(context,
env->refresh_string(),
Integer::New(env->isolate(), soa.refresh)).FromJust();
Integer::New(env->isolate(), refresh)).FromJust();
soa_record->Set(context,
env->retry_string(),
Integer::New(env->isolate(), soa.retry)).FromJust();
Integer::New(env->isolate(), retry)).FromJust();
soa_record->Set(context,
env->expire_string(),
Integer::New(env->isolate(), soa.expire)).FromJust();
Integer::New(env->isolate(), expire)).FromJust();
soa_record->Set(context,
env->minttl_string(),
Integer::New(env->isolate(), soa.minttl)).FromJust();
Integer::New(env->isolate(), minttl)).FromJust();
soa_record->Set(context,
env->type_string(),
env->dns_soa_string()).FromJust();
free(soa.nsname);
free(soa.hostmaster);
*ret = handle_scope.Escape(soa_record);
break;
}
free(rr_name);
ptr += rr_len;
}
free(name);
if (status != ARES_SUCCESS) {
return status == ARES_EBADNAME ? ARES_EBADRESP : status;
}
return ARES_SUCCESS;
}

0 comments on commit acb363f

Please sign in to comment.