New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

tangerine

Package Overview
Dependencies
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tangerine - npm Package Compare versions

Comparing version 1.4.5 to 1.4.6

181

index.js

@@ -10,4 +10,7 @@ const dns = require('node:dns');

const { toASCII } = require('punycode/');
const autoBind = require('auto-bind');
const getStream = require('get-stream');
const hostile = require('hostile');
const ipaddr = require('ipaddr.js');

@@ -21,5 +24,4 @@ const mergeOptions = require('merge-options');

const structuredClone = require('@ungap/structured-clone').default;
const { Hosts } = require('hosts-parser');
const { getService } = require('port-numbers');
// eslint-disable-next-line import/order
const { toASCII } = require('punycode/');

@@ -30,2 +32,9 @@ const pkg = require('./package.json');

const hosts = new Hosts(
hostile
.get()
.map((arr) => arr.join(' '))
.join('\n')
);
// dynamically import dohdec

@@ -154,3 +163,4 @@ let dohdec;

dns.SERVFAIL,
dns.TIMEOUT
dns.TIMEOUT,
'EINVAL'
]);

@@ -646,39 +656,112 @@

// <https://github.com/c-ares/c-ares/blob/38b30bc922c21faa156939bde15ea35332c30e08/src/lib/ares_getaddrinfo.c#L407>
// <https://www.rfc-editor.org/rfc/rfc6761.html#section-6.3>
//
// > 'localhost and any domains falling within .localhost'
//
// if no system loopback match, then revert to the default
// <https://github.com/c-ares/c-ares/blob/38b30bc922c21faa156939bde15ea35332c30e08/src/lib/ares__addrinfo_localhost.c#L224-L229>
// - IPv4 = '127.0.0.1"
// - IPv6 = "::1"
//
let resolve4;
let resolve6;
// sorted in reverse to match behavior of lookup
for (const rule of hosts._origin.reverse()) {
if (
rule.hostname.toLowerCase() !== name.toLowerCase() &&
rule.ip !== name
)
continue;
const type = isIP(rule.ip);
if (!resolve4 && type === 4) resolve4 = [rule.ip];
else if (!resolve6 && type === 6) resolve6 = [rule.ip];
if (resolve4 && resolve6) break;
}
// if no matches found for resolve4 and resolve6 and it was localhost
// (this is a safeguard in case host file is missing these)
if (
name.toLowerCase() === 'localhost' ||
name.toLowerCase() === 'localhost.'
) {
if (!resolve4) resolve4 = ['127.0.0.1'];
if (!resolve6) resolve6 = ['::1'];
}
if (isIPv4(name)) {
resolve4 = [name];
resolve6 = [];
} else if (isIPv6(name)) {
resolve6 = [name];
resolve4 = [];
}
// resolve the first A or AAAA record (conditionally)
const results = await Promise.all(
[
Array.isArray(resolve4)
? Promise.resolve(resolve4)
: this.resolve4(name, { purgeCache, noThrowOnNODATA: true }),
Array.isArray(resolve6)
? Promise.resolve(resolve6)
: this.resolve6(name, { purgeCache, noThrowOnNODATA: true })
].map((p) => p.catch((err) => err))
);
const errors = [];
let answers = [];
try {
answers = await Promise.all([
this.resolve4(name, { purgeCache, noThrowOnNODATA: true }),
this.resolve6(name, { purgeCache, noThrowOnNODATA: true })
]);
// default node behavior seems to return IPv4 by default always regardless
answers =
answers[0].length > 0 &&
(typeof options.family === 'undefined' || options.family === 0)
? answers[0]
: answers.flat();
} catch (_err) {
debug(_err);
for (const result of results) {
if (result instanceof Error) {
errors.push(result);
} else {
answers.push(result);
}
}
// this will most likely be instanceof AggregateError
if (_err instanceof AggregateError) {
const err = this.constructor.combineErrors(_err.errors);
if (
answers.length === 0 &&
errors.length > 0 &&
errors.every((e) => e.code === errors[0].code)
) {
const err = this.constructor.createError(
name,
'',
errors[0].code === dns.BADNAME ? dns.NOTFOUND : errors[0].code
);
// remap and perform syscall
err.syscall = 'getaddrinfo';
err.message = err.message.replace('query', 'getaddrinfo');
err.errno = -3008;
throw err;
}
/*
//
// NOTE: we probably should handle this differently (?)
// (not sure what native nodejs dns module does for different errors - haven't checked yet)
//
if (errors.every((e) => e.code !== 'ENODATA')) {
const err = this.constructor.combineErrors(errors);
err.hostname = name;
// remap and perform syscall
err.syscall = 'getaddrinfo';
err.message = err.message.replace('query', 'getaddrinfo');
if (!err.code)
err.code = _err.errors.find((e) => e.code)?.code || dns.BADRESP;
err.code = errors.find((e) => e.code)?.code || dns.BADRESP;
if (!err.errno)
err.errno = _err.errors.find((e) => e.errno)?.errno || undefined;
err.errno = errors.find((e) => e.errno)?.errno || undefined;
throw err;
}
*/
const err = this.constructor.createError(name, '', _err.code, _err.errno);
// remap and perform syscall
err.syscall = 'getaddrinfo';
err.error = _err;
throw err;
}
// default node behavior seems to return IPv4 by default always regardless
if (answers.length > 0)
answers =
answers[0].length > 0 &&
(typeof options.family === 'undefined' || options.family === 0)
? answers[0]
: answers.flat();

@@ -690,3 +773,4 @@ // if no results then throw ENODATA

err.syscall = 'getaddrinfo';
// err.errno = -3008;
err.message = err.message.replace('query', 'getaddrinfo');
err.errno = -3008;
throw err;

@@ -844,5 +928,6 @@ }

if (!isIP(ip)) {
const err = this.constructor.createError(ip, '', dns.EINVAL);
const err = this.constructor.createError(ip, '', 'EINVAL');
err.message = `getHostByAddr EINVAL ${err.hostname}`;
err.syscall = 'getHostByAddr';
// err.errno = -22;
err.errno = -22;
if (!ip) delete err.hostname;

@@ -852,4 +937,8 @@ throw err;

// edge case where localhost IP returns empty
if (ip === '127.0.0.1' || ip === '::1') return [];
// reverse the IP address
if (!dohdec) await pWaitFor(() => Boolean(dohdec));
const name = dohdec.DNSoverHTTPS.reverse(ip);

@@ -1281,9 +1370,18 @@

const results = await pMap(
this.constructor.ANY_TYPES,
this.#resolveByType(name, options, abortController),
// <https://developers.cloudflare.com/fundamentals/api/reference/limits/>
{ concurrency: this.options.concurrency, signal: abortController.signal }
);
return results.flat().filter(Boolean);
try {
const results = await pMap(
this.constructor.ANY_TYPES,
this.#resolveByType(name, options, abortController),
// <https://developers.cloudflare.com/fundamentals/api/reference/limits/>
{
concurrency: this.options.concurrency,
signal: abortController.signal
}
);
return results.flat().filter(Boolean);
} catch (err) {
err.syscall = 'queryAny';
err.message = `queryAny ${err.code} ${name}`;
throw err;
}
}

@@ -1342,2 +1440,7 @@

// edge case where c-ares detects "." as start of string
// <https://github.com/c-ares/c-ares/blob/38b30bc922c21faa156939bde15ea35332c30e08/src/lib/ares_getaddrinfo.c#L829>
if (name.startsWith('.') || name.includes('..'))
throw this.constructor.createError(name, rrtype, dns.BADNAME);
// purge cache support

@@ -1725,3 +1828,3 @@ let purgeCache;

} catch (err) {
console.error(err);
this.options.logger.error(err, { name, rrtype, options, answer });
throw err;

@@ -1728,0 +1831,0 @@ }

{
"name": "tangerine",
"description": "Tangerine is the best Node.js drop-in replacement for dns.promises.Resolver using DNS over HTTPS (\"DoH\") via undici with built-in retries, timeouts, smart server rotation, AbortControllers, and caching support for multiple backends (with TTL and purge support).",
"version": "1.4.5",
"version": "1.4.6",
"author": "Forward Email (https://forwardemail.net)",

@@ -18,2 +18,4 @@ "bugs": {

"get-stream": "6",
"hostile": "^1.3.3",
"hosts-parser": "^0.3.2",
"ipaddr.js": "^2.0.1",

@@ -20,0 +22,0 @@ "merge-options": "3.0.4",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc