@@ -209,6 +209,23 @@ Local<Array> AddrTTLToArray( |
209 | 209 | return Array::New(env->isolate(), ttls.out(), naddrttls); |
210 | 210 | } |
211 | 211 |
|
| 212 | +int GetAnswerCountForTTLBuffer(const unsigned char* buf, int len) { |
| 213 | + static constexpr int kDNSAnswerCountOffset = 6; |
| 214 | + static constexpr int kAresDefaultTTLBufferLength = 256; |
| 215 | + if (len <= kDNSAnswerCountOffset + 1) { |
| 216 | + return kAresDefaultTTLBufferLength; |
| 217 | + } |
| 218 | + |
| 219 | + const int answer_count = (static_cast<int>(buf[kDNSAnswerCountOffset]) << 8) | |
| 220 | + static_cast<int>(buf[kDNSAnswerCountOffset + 1]); |
| 221 | + return answer_count == 0 ? 1 : answer_count; |
| 222 | +} |
| 223 | + |
| 224 | +template <typename T> |
| 225 | +std::vector<T> MakeAddrTTLBuffer(const unsigned char* buf, int len) { |
| 226 | + return std::vector<T>(GetAnswerCountForTTLBuffer(buf, len)); |
| 227 | +} |
| 228 | + |
212 | 229 | Maybe<int> ParseGeneralReply(Environment* env, |
213 | 230 | const unsigned char* buf, |
214 | 231 | int len, |
@@ -1105,11 +1122,12 @@ Maybe<int> AnyTraits::Parse(QueryAnyWrap* wrap, |
1105 | 1122 | int type, status, old_count; |
1106 | 1123 |
|
1107 | 1124 | /* Parse A records or CNAME records */ |
1108 | | - ares_addrttl addrttls[256]; |
1109 | | - int naddrttls = arraysize(addrttls); |
| 1125 | + std::vector<ares_addrttl> addrttls = |
| 1126 | + MakeAddrTTLBuffer<ares_addrttl>(buf, len); |
| 1127 | + int naddrttls = static_cast<int>(addrttls.size()); |
1110 | 1128 |
|
1111 | 1129 | type = ns_t_cname_or_a; |
1112 | | - if (!ParseGeneralReply(env, buf, len, &type, ret, addrttls, &naddrttls) |
| 1130 | + if (!ParseGeneralReply(env, buf, len, &type, ret, addrttls.data(), &naddrttls) |
1113 | 1131 | .To(&status)) { |
1114 | 1132 | return Nothing<int>(); |
1115 | 1133 | } |
@@ -1182,11 +1200,13 @@ Maybe<int> AnyTraits::Parse(QueryAnyWrap* wrap, |
1182 | 1200 | } |
1183 | 1201 |
|
1184 | 1202 | /* Parse AAAA records */ |
1185 | | - ares_addr6ttl addr6ttls[256]; |
1186 | | - int naddr6ttls = arraysize(addr6ttls); |
| 1203 | + std::vector<ares_addr6ttl> addr6ttls = |
| 1204 | + MakeAddrTTLBuffer<ares_addr6ttl>(buf, len); |
| 1205 | + int naddr6ttls = static_cast<int>(addr6ttls.size()); |
1187 | 1206 |
|
1188 | 1207 | type = ns_t_aaaa; |
1189 | | - if (!ParseGeneralReply(env, buf, len, &type, ret, addr6ttls, &naddr6ttls) |
| 1208 | + if (!ParseGeneralReply( |
| 1209 | + env, buf, len, &type, ret, addr6ttls.data(), &naddr6ttls) |
1190 | 1210 | .To(&status)) { |
1191 | 1211 | return Nothing<int>(); |
1192 | 1212 | } |
@@ -1374,20 +1394,22 @@ Maybe<int> ATraits::Parse(QueryAWrap* wrap, |
1374 | 1394 | HandleScope handle_scope(env->isolate()); |
1375 | 1395 | Context::Scope context_scope(env->context()); |
1376 | 1396 |
|
1377 | | - ares_addrttl addrttls[256]; |
1378 | | - int naddrttls = arraysize(addrttls), status; |
| 1397 | + std::vector<ares_addrttl> addrttls = |
| 1398 | + MakeAddrTTLBuffer<ares_addrttl>(buf, len); |
| 1399 | + int naddrttls = static_cast<int>(addrttls.size()), status; |
1379 | 1400 | Local<Array> ret = Array::New(env->isolate()); |
1380 | 1401 |
|
1381 | 1402 | int type = ns_t_a; |
1382 | | - if (!ParseGeneralReply(env, buf, len, &type, ret, addrttls, &naddrttls) |
| 1403 | + if (!ParseGeneralReply(env, buf, len, &type, ret, addrttls.data(), &naddrttls) |
1383 | 1404 | .To(&status)) { |
1384 | 1405 | return Nothing<int>(); |
1385 | 1406 | } |
1386 | 1407 | if (status != ARES_SUCCESS) { |
1387 | 1408 | return Just<int>(status); |
1388 | 1409 | } |
1389 | 1410 |
|
1390 | | - Local<Array> ttls = AddrTTLToArray<ares_addrttl>(env, addrttls, naddrttls); |
| 1411 | + Local<Array> ttls = |
| 1412 | + AddrTTLToArray<ares_addrttl>(env, addrttls.data(), naddrttls); |
1391 | 1413 |
|
1392 | 1414 | wrap->CallOnComplete(ret, ttls); |
1393 | 1415 | return Just<int>(ARES_SUCCESS); |
@@ -1406,20 +1428,22 @@ Maybe<int> AaaaTraits::Parse(QueryAaaaWrap* wrap, |
1406 | 1428 | HandleScope handle_scope(env->isolate()); |
1407 | 1429 | Context::Scope context_scope(env->context()); |
1408 | 1430 |
|
1409 | | - ares_addr6ttl addrttls[256]; |
1410 | | - int naddrttls = arraysize(addrttls), status; |
| 1431 | + std::vector<ares_addr6ttl> addrttls = |
| 1432 | + MakeAddrTTLBuffer<ares_addr6ttl>(buf, len); |
| 1433 | + int naddrttls = static_cast<int>(addrttls.size()), status; |
1411 | 1434 | Local<Array> ret = Array::New(env->isolate()); |
1412 | 1435 |
|
1413 | 1436 | int type = ns_t_aaaa; |
1414 | | - if (!ParseGeneralReply(env, buf, len, &type, ret, addrttls, &naddrttls) |
| 1437 | + if (!ParseGeneralReply(env, buf, len, &type, ret, addrttls.data(), &naddrttls) |
1415 | 1438 | .To(&status)) { |
1416 | 1439 | return Nothing<int>(); |
1417 | 1440 | } |
1418 | 1441 | if (status != ARES_SUCCESS) { |
1419 | 1442 | return Just<int>(status); |
1420 | 1443 | } |
1421 | 1444 |
|
1422 | | - Local<Array> ttls = AddrTTLToArray<ares_addr6ttl>(env, addrttls, naddrttls); |
| 1445 | + Local<Array> ttls = |
| 1446 | + AddrTTLToArray<ares_addr6ttl>(env, addrttls.data(), naddrttls); |
1423 | 1447 |
|
1424 | 1448 | wrap->CallOnComplete(ret, ttls); |
1425 | 1449 | return Just<int>(ARES_SUCCESS); |
|