Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

url: replace "magic" numbers by constants #19035

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions lib/internal/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,34 @@ module.exports = {
CHAR_DOT: 46, /* . */
CHAR_FORWARD_SLASH: 47, /* / */
CHAR_BACKWARD_SLASH: 92, /* \ */
CHAR_VERTICAL_LINE: 124, /* | */
CHAR_COLON: 58, /* : */
CHAR_QUESTION_MARK: 63, /* ? */
CHAR_UNDERSCORE: 95, /* _ */
CHAR_LINE_FEED: 10, /* \n */
CHAR_CARRIAGE_RETURN: 13, /* \r */
CHAR_TAB: 9, /* \t */
CHAR_FORM_FEED: 12, /* \f */
CHAR_EXCLAMATION_MARK: 33, /* ! */
CHAR_HASH: 35, /* # */
CHAR_SPACE: 32, /* */
CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */
CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */
CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */
CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */
CHAR_LEFT_ANGLE_BRACKET: 60, /* < */
CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */
CHAR_LEFT_CURLY_BRACKET: 123, /* { */
CHAR_RIGHT_CURLY_BRACKET: 125, /* } */
CHAR_HYPHEN_MINUS: 45, /* - */
CHAR_PLUS: 43, /* + */
CHAR_DOUBLE_QUOTE: 34, /* " */
CHAR_SINGLE_QUOTE: 39, /* ' */
CHAR_PERCENT: 37, /* % */
CHAR_SEMICOLON: 59, /* ; */
CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */
CHAR_GRAVE_ACCENT: 96, /* ` */
CHAR_AT: 64, /* @ */

// Digits
CHAR_0: 48, /* 0 */
Expand Down
137 changes: 88 additions & 49 deletions lib/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,43 @@ const slashedProtocol = {
'file:': true
};
const querystring = require('querystring');
const {
CHAR_SPACE,
CHAR_TAB,
CHAR_CARRIAGE_RETURN,
CHAR_LINE_FEED,
CHAR_FORM_FEED,
CHAR_NO_BREAK_SPACE,
CHAR_ZERO_WIDTH_NOBREAK_SPACE,
CHAR_HASH,
CHAR_FORWARD_SLASH,
CHAR_LEFT_SQUARE_BRACKET,
CHAR_RIGHT_SQUARE_BRACKET,
CHAR_LEFT_ANGLE_BRACKET,
CHAR_RIGHT_ANGLE_BRACKET,
CHAR_LEFT_CURLY_BRACKET,
CHAR_RIGHT_CURLY_BRACKET,
CHAR_QUESTION_MARK,
CHAR_LOWERCASE_A,
CHAR_LOWERCASE_Z,
CHAR_UPPERCASE_A,
CHAR_UPPERCASE_Z,
CHAR_DOT,
CHAR_0,
CHAR_9,
CHAR_HYPHEN_MINUS,
CHAR_PLUS,
CHAR_UNDERSCORE,
CHAR_DOUBLE_QUOTE,
CHAR_SINGLE_QUOTE,
CHAR_PERCENT,
CHAR_SEMICOLON,
CHAR_BACKWARD_SLASH,
CHAR_CIRCUMFLEX_ACCENT,
CHAR_GRAVE_ACCENT,
CHAR_VERTICAL_LINE,
CHAR_AT,
} = require('internal/constants');

function urlParse(url, parseQueryString, slashesDenoteHost) {
if (url instanceof Url) return url;
Expand Down Expand Up @@ -119,13 +156,13 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) {
const code = url.charCodeAt(i);

// Find first and last non-whitespace characters for trimming
const isWs = code === 32/* */ ||
code === 9/*\t*/ ||
code === 13/*\r*/ ||
code === 10/*\n*/ ||
code === 12/*\f*/ ||
code === 160/*\u00A0*/ ||
code === 65279/*\uFEFF*/;
const isWs = code === CHAR_SPACE ||
code === CHAR_TAB ||
code === CHAR_CARRIAGE_RETURN ||
code === CHAR_LINE_FEED ||
code === CHAR_FORM_FEED ||
code === CHAR_NO_BREAK_SPACE ||
code === CHAR_ZERO_WIDTH_NOBREAK_SPACE;
if (start === -1) {
if (isWs)
continue;
Expand All @@ -143,20 +180,20 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) {
// Only convert backslashes while we haven't seen a split character
if (!split) {
switch (code) {
case 35: // '#'
case CHAR_HASH:
hasHash = true;
// Fall through
case 63: // '?'
case CHAR_QUESTION_MARK:
split = true;
break;
case 92: // '\\'
case CHAR_BACKWARD_SLASH:
if (i - lastPos > 0)
rest += url.slice(lastPos, i);
rest += '/';
lastPos = i + 1;
break;
}
} else if (!hasHash && code === 35/*#*/) {
} else if (!hasHash && code === CHAR_HASH) {
hasHash = true;
}
}
Expand Down Expand Up @@ -218,8 +255,8 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) {
// resolution will treat //foo/bar as host=foo,path=bar because that's
// how the browser resolves relative URLs.
if (slashesDenoteHost || proto || hostPattern.test(rest)) {
var slashes = rest.charCodeAt(0) === 47/*/*/ &&
rest.charCodeAt(1) === 47/*/*/;
var slashes = rest.charCodeAt(0) === CHAR_FORWARD_SLASH &&
rest.charCodeAt(1) === CHAR_FORWARD_SLASH;
if (slashes && !(proto && hostlessProtocol[proto])) {
rest = rest.slice(2);
this.slashes = true;
Expand Down Expand Up @@ -249,35 +286,35 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) {
var nonHost = -1;
for (i = 0; i < rest.length; ++i) {
switch (rest.charCodeAt(i)) {
case 9: // '\t'
case 10: // '\n'
case 13: // '\r'
case 32: // ' '
case 34: // '"'
case 37: // '%'
case 39: // '\''
case 59: // ';'
case 60: // '<'
case 62: // '>'
case 92: // '\\'
case 94: // '^'
case 96: // '`'
case 123: // '{'
case 124: // '|'
case 125: // '}'
case CHAR_TAB:
case CHAR_LINE_FEED:
case CHAR_CARRIAGE_RETURN:
case CHAR_SPACE:
case CHAR_DOUBLE_QUOTE:
case CHAR_PERCENT:
case CHAR_SINGLE_QUOTE:
case CHAR_SEMICOLON:
case CHAR_LEFT_ANGLE_BRACKET:
case CHAR_RIGHT_ANGLE_BRACKET:
case CHAR_BACKWARD_SLASH:
case CHAR_CIRCUMFLEX_ACCENT:
case CHAR_GRAVE_ACCENT:
case CHAR_LEFT_CURLY_BRACKET:
case CHAR_VERTICAL_LINE:
case CHAR_RIGHT_CURLY_BRACKET:
// Characters that are never ever allowed in a hostname from RFC 2396
if (nonHost === -1)
nonHost = i;
break;
case 35: // '#'
case 47: // '/'
case 63: // '?'
case CHAR_HASH:
case CHAR_FORWARD_SLASH:
case CHAR_QUESTION_MARK:
// Find the first instance of any host-ending characters
if (nonHost === -1)
nonHost = i;
hostEnd = i;
break;
case 64: // '@'
case CHAR_AT:
// At this point, either we have an explicit point where the
// auth portion cannot go past, or the last @ char is the decider.
atSign = i;
Expand Down Expand Up @@ -312,8 +349,8 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) {

// if hostname begins with [ and ends with ]
// assume that it's an IPv6 address.
var ipv6Hostname = hostname.charCodeAt(0) === 91/*[*/ &&
hostname.charCodeAt(hostname.length - 1) === 93/*]*/;
var ipv6Hostname = hostname.charCodeAt(0) === CHAR_LEFT_SQUARE_BRACKET &&
hostname.charCodeAt(hostname.length - 1) === CHAR_RIGHT_SQUARE_BRACKET;

// validate a little.
if (!ipv6Hostname) {
Expand Down Expand Up @@ -367,11 +404,11 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) {
var hashIdx = -1;
for (i = 0; i < rest.length; ++i) {
const code = rest.charCodeAt(i);
if (code === 35/*#*/) {
if (code === CHAR_HASH) {
this.hash = rest.slice(i);
hashIdx = i;
break;
} else if (code === 63/*?*/ && questionIdx === -1) {
} else if (code === CHAR_QUESTION_MARK && questionIdx === -1) {
questionIdx = i;
}
}
Expand Down Expand Up @@ -422,13 +459,13 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) {
function validateHostname(self, rest, hostname) {
for (var i = 0; i < hostname.length; ++i) {
const code = hostname.charCodeAt(i);
const isValid = (code >= 97/*a*/ && code <= 122/*z*/) ||
code === 46/*.*/ ||
(code >= 65/*A*/ && code <= 90/*Z*/) ||
(code >= 48/*0*/ && code <= 57/*9*/) ||
code === 45/*-*/ ||
code === 43/*+*/ ||
code === 95/*_*/ ||
const isValid = (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z) ||
code === CHAR_DOT ||
(code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) ||
(code >= CHAR_0 && code <= CHAR_9) ||
code === CHAR_HYPHEN_MINUS ||
code === CHAR_PLUS ||
code === CHAR_UNDERSCORE ||
code > 127;

// Invalid host character
Expand Down Expand Up @@ -542,13 +579,13 @@ Url.prototype.format = function format() {
var lastPos = 0;
for (var i = 0; i < pathname.length; ++i) {
switch (pathname.charCodeAt(i)) {
case 35: // '#'
case CHAR_HASH:
if (i - lastPos > 0)
newPathname += pathname.slice(lastPos, i);
newPathname += '%23';
lastPos = i + 1;
break;
case 63: // '?'
case CHAR_QUESTION_MARK:
if (i - lastPos > 0)
newPathname += pathname.slice(lastPos, i);
newPathname += '%3F';
Expand All @@ -567,7 +604,7 @@ Url.prototype.format = function format() {
// unless they had them to begin with.
if (this.slashes || slashedProtocol[protocol]) {
if (this.slashes || host) {
if (pathname && pathname.charCodeAt(0) !== 47/*/*/)
if (pathname && pathname.charCodeAt(0) !== CHAR_FORWARD_SLASH)
pathname = '/' + pathname;
host = '//' + host;
} else if (protocol.length >= 4 &&
Expand All @@ -581,8 +618,10 @@ Url.prototype.format = function format() {

search = search.replace(/#/g, '%23');

if (hash && hash.charCodeAt(0) !== 35/*#*/) hash = '#' + hash;
if (search && search.charCodeAt(0) !== 63/*?*/) search = '?' + search;
if (hash && hash.charCodeAt(0) !== CHAR_HASH)
hash = '#' + hash;
if (search && search.charCodeAt(0) !== CHAR_QUESTION_MARK)
search = '?' + search;

return protocol + host + pathname + search + hash;
};
Expand Down