0
0
mirror of https://github.com/nodejs/node.git synced 2024-12-01 16:10:02 +01:00
nodejs/lib/internal/net.js
Joyee Cheung 1432065e9d
lib: correct error.errno to always be numeric
Historically `error.errno` of system errors thrown by Node.js
can sometimes be the same as `err.code`, which are string
representations of the error numbers. This is useless and incorrect,
and results in an information loss for users since then they
will have to resort to something like
`process.binding('uv'[`UV_${errno}`])` to get to the numeric
error codes.

This patch corrects this behavior by always setting `error.errno`
to be negative numbers. For fabricated errors like `ENOTFOUND`,
`error.errno` is now undefined since there is no numeric equivalent
for them anyway. For c-ares errors, `error.errno` is now undefined
because the numeric representations (negated) can be in conflict
with libuv error codes - this is fine since numeric codes was
not available for c-ares errors anyway.

Users can use the public API `util.getSystemErrorName(errno)`
to retrieve string codes for these numbers.

PR-URL: https://github.com/nodejs/node/pull/28140
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
2019-06-17 10:18:09 +08:00

74 lines
2.0 KiB
JavaScript

'use strict';
const Buffer = require('buffer').Buffer;
const { writeBuffer } = internalBinding('fs');
const errors = require('internal/errors');
// IPv4 Segment
const v4Seg = '(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
const v4Str = `(${v4Seg}[.]){3}${v4Seg}`;
const IPv4Reg = new RegExp(`^${v4Str}$`);
// IPv6 Segment
const v6Seg = '(?:[0-9a-fA-F]{1,4})';
const IPv6Reg = new RegExp('^(' +
`(?:${v6Seg}:){7}(?:${v6Seg}|:)|` +
`(?:${v6Seg}:){6}(?:${v4Str}|:${v6Seg}|:)|` +
`(?:${v6Seg}:){5}(?::${v4Str}|(:${v6Seg}){1,2}|:)|` +
`(?:${v6Seg}:){4}(?:(:${v6Seg}){0,1}:${v4Str}|(:${v6Seg}){1,3}|:)|` +
`(?:${v6Seg}:){3}(?:(:${v6Seg}){0,2}:${v4Str}|(:${v6Seg}){1,4}|:)|` +
`(?:${v6Seg}:){2}(?:(:${v6Seg}){0,3}:${v4Str}|(:${v6Seg}){1,5}|:)|` +
`(?:${v6Seg}:){1}(?:(:${v6Seg}){0,4}:${v4Str}|(:${v6Seg}){1,6}|:)|` +
`(?::((?::${v6Seg}){0,5}:${v4Str}|(?::${v6Seg}){1,7}|:))` +
')(%[0-9a-zA-Z]{1,})?$');
function isIPv4(s) {
return IPv4Reg.test(s);
}
function isIPv6(s) {
return IPv6Reg.test(s);
}
function isIP(s) {
if (isIPv4(s)) return 4;
if (isIPv6(s)) return 6;
return 0;
}
// Check that the port number is not NaN when coerced to a number,
// is an integer and that it falls within the legal range of port numbers.
function isLegalPort(port) {
if ((typeof port !== 'number' && typeof port !== 'string') ||
(typeof port === 'string' && port.trim().length === 0))
return false;
return +port === (+port >>> 0) && port <= 0xFFFF;
}
function makeSyncWrite(fd) {
return function(chunk, enc, cb) {
if (enc !== 'buffer')
chunk = Buffer.from(chunk, enc);
this._handle.bytesWritten += chunk.length;
const ctx = {};
writeBuffer(fd, chunk, 0, chunk.length, null, undefined, ctx);
if (ctx.errno !== undefined) {
const ex = errors.uvException(ctx);
ex.errno = ctx.errno;
return cb(ex);
}
cb();
};
}
module.exports = {
isIP,
isIPv4,
isIPv6,
isLegalPort,
makeSyncWrite,
normalizedArgsSymbol: Symbol('normalizedArgs')
};