Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

url-parse

Package Overview
Dependencies
Maintainers
2
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

url-parse - npm Package Compare versions

Comparing version 0.2.3 to 1.0.0

2

fuzzy.js
'use strict';
var URL = require('./')
, url = new URL();
, url = new URL('');

@@ -6,0 +6,0 @@ /**

@@ -5,8 +5,27 @@ 'use strict';

, lolcation = require('./lolcation')
, qs = require('querystringify');
, qs = require('querystringify')
, relativere = /^\/(?!\/)/;
var keys = ',,protocol,username,password,host,hostname,port,pathname,query,hash'.split(',')
, inherit = { protocol: 1, host: 1, hostname: 1 }
, relativere = /^\/(?!\/)/
, parts = keys.length;
/**
* These are the parse instructions for the URL parsers, it informs the parser
* about:
*
* 0. The char it Needs to parse, if it's a string it should be done using
* indexOf, RegExp using exec and NaN means set as current value.
* 1. The property we should set when parsing this value.
* 2. Indication if it's backwards or forward parsing, when set as number it's
* the value of extra chars that should be split off.
* 3. Inherit from location if non existing in the parser.
* 4. `toLowerCase` the resulting value.
*/
var instructions = [
['#', 'hash'], // Extract from the back.
['?', 'query'], // Extract from the back.
['//', 'protocol', 2, 1, 1], // Extract from the front.
['/', 'pathname'], // Extract from the back.
['@', 'auth', 1], // Extract from the front.
[NaN, 'host', undefined, 1, 1], // Set left over value.
[/\:(\d+)$/, 'port'], // RegExp the back.
[NaN, 'hostname', undefined, 1, 1] // Set left over.
];

@@ -29,42 +48,7 @@ /**

//
// Story time children:
//
// FireFox 34 has some problems with their Regular Expression engine and
// executing a RegExp can cause a `too much recursion` error. We initially fixed
// this by moving the Regular Expression in the URL constructor so it's created
// every single time. This fixed it for some URL's but the more complex the
// URL's get the easier it is to trigger. Complexer URL like:
//
// https://www.mozilla.org/en-US/firefox/34.0/whatsnew/?oldversion=33.1
//
// Still triggered the recursion error. After talking with Chrome and FireFox
// engineers it seemed to be caused by:
//
// https://code.google.com/p/v8/issues/detail?id=430
//
// As FireFox started using Chrome's RegExp engine. After testing various of
// workarounds I finally stumbled upon this gem, use new RegExp as it sometimes
// behaves different then a RegExp literal. The biggest problem with this
// FireFox problem is that it's super hard to reproduce as our "normal" test
// suite doesn't catch it. The only way to reproduce it was run the parser in
// jsperf.com (uses the benchmark module from npm) and supply it the URL
// mentioned above as URL to parse.
//
// Steps for compiling the new RegExp:
//
// 1. Take the regular RegExp as seen below.
// 2. Escape the RegExp using XRegExp.escape from http://xregexp.com/tests/
// 3. ??
// 4. Profit.
//
// RegExp source: /^(?:(?:(([^:\/#\?]+:)?(?:(?:\/\/)(?:(?:(?:([^:@\/#\?]+)(?:\:([^:@\/#\?]*))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((?:\/?(?:[^\/\?#]+\/+)*)(?:[^\?#]*)))?(\?[^#]+)?)(#.*)?/
//
var regexp = new RegExp('\^\(\?:\(\?:\(\(\[\^:\\/\#\\\?\]\+:\)\?\(\?:\(\?:\\/\\/\)\(\?:\(\?:\(\?:\(\[\^:@\\/\#\\\?\]\+\)\(\?:\\:\(\[\^:@\\/\#\\\?\]\*\)\)\?\)@\)\?\(\(\[\^:\\/\#\\\?\\\]\\\[\]\+\|\\\[\[\^\\/\\\]@\#\?\]\+\\\]\)\(\?:\\:\(\[0\-9\]\+\)\)\?\)\)\?\)\?\)\?\(\(\?:\\/\?\(\?:\[\^\\/\\\?\#\]\+\\/\+\)\*\)\(\?:\[\^\\\?\#\]\*\)\)\)\?\(\\\?\[\^\#\]\+\)\?\)\(\#\.\*\)\?')
, relative = relativere.test(address)
, bits = regexp.exec(address)
var relative = relativere.test(address)
, parse, instruction, index, key
, type = typeof location
, url = this
, i = 0
, key;
, i = 0;

@@ -93,13 +77,33 @@ //

for (; i < parts; key = keys[++i]) {
if (!key) continue;
for (; i < instructions.length; i++) {
instruction = instructions[i];
parse = instruction[0];
key = instruction[1];
url[key] = bits[i] || (key in inherit || ('port' === key && relative) ? location[key] || '' : '');
if (parse !== parse) {
url[key] = address;
} else if ('string' === typeof parse) {
if (~(index = address.indexOf(parse))) {
if ('number' === typeof instruction[2]) {
url[key] = address.slice(0, index);
address = address.slice(index + instruction[2]);
} else {
url[key] = address.slice(index);
address = address.slice(0, index);
}
}
} else if (index = parse.exec(address)) {
url[key] = index[1];
address = address.slice(0, address.length - index[0].length);
}
url[key] = url[key] || (instruction[3] || ('port' === key && relative) ? location[key] || '' : '');
//
// The protocol, host, host name should always be lower cased even if they
// are supplied in uppercase. This way, when people generate an `origin`
// it be correct.
// Hostname, host and protocol should be lowercased so they can be used to
// create a proper `origin`.
//
if (i === 2 || i === 5 || i === 6) url[key] = url[key].toLowerCase();
if (instruction[4]) {
url[key] = url[key].toLowerCase();
}
}

@@ -125,2 +129,12 @@

//
// Parse down the `auth` for the username and password.
//
url.username = url.password = '';
if (url.auth) {
instruction = url.auth.split(':');
url.username = instruction[0] || '';
url.password = instruction[1] || '';
}
//
// The href is just the compiled result.

@@ -127,0 +141,0 @@ //

{
"name": "url-parse",
"version": "0.2.3",
"version": "1.0.0",
"description": "Parse URL in node using the URL module and in the browser using the DOM",

@@ -10,3 +10,3 @@ "main": "index.js",

"test-travis": "istanbul cover node_modules/.bin/_mocha --report lcovonly -- --reporter spec --ui bdd ./test.js",
"browserify": "mkdir dist && browserify index.js -o dist/url-parse.js --standalone URLParse",
"browserify": "mkdir -p dist && browserify index.js -o dist/url-parse.js --standalone URLParse",
"phantomjs": "mochify --reporter spec --ui bdd ./test.js",

@@ -29,6 +29,6 @@ "testling": "testling -u"

"devDependencies": {
"assume": "0.0.x",
"browserify": "7.0.x",
"assume": "1.0.x",
"browserify": "8.1.x",
"istanbul": "0.3.x",
"mocha": "2.0.x",
"mocha": "2.1.x",
"mochify": "2.1.x",

@@ -35,0 +35,0 @@ "pre-commit": "0.0.x",

@@ -13,3 +13,6 @@ # url-parse

module still have a really small foot print as this module's main intention is
to be bundled with client-side code.
to be bundled with client-side code. The only problem however with a RegExp
based solution is that it required a lot of lookups causing major problems in
FireFox. So the last and the current solution was a pure string parsing
solution which chops up the URL in smaller pieces.

@@ -16,0 +19,0 @@ In addition to URL parsing we also expose the bundled `querystringify` module.

@@ -78,9 +78,2 @@ describe('url-parse', function () {

it('does not lowercase the USER:PASS', function () {
var url = 'HTTP://USER:PASS@EXAMPLE.COM';
assume(parse(url).username).equals('USER');
assume(parse(url).password).equals('PASS');
});
it('does not lowercase the path', function () {

@@ -102,8 +95,111 @@ var url = 'HTTP://X.COM/Y/Z';

it('accepts @ in pathnames', function () {
var url = 'http://mt0.google.com/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=';
it('understands an / as pathname', function () {
var url = 'http://example.com:80/'
, parsed = parse(url);
assume(parse(url).pathname).equals('/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=');
assume(parsed.port).equals('');
assume(parsed.username).equals('');
assume(parsed.password).equals('');
assume(parsed.pathname).equals('/');
assume(parsed.host).equals('example.com');
assume(parsed.hostname).equals('example.com');
assume(parsed.href).equals('http://example.com/');
});
it('does not care about spaces', function () {
var url = 'http://x.com/path?that\'s#all, folks'
, parsed = parse(url);
assume(parsed.port).equals('');
assume(parsed.username).equals('');
assume(parsed.password).equals('');
assume(parsed.pathname).equals('/path');
assume(parsed.hash).equal('#all, folks');
assume(parsed.query).equal('?that\'s');
assume(parsed.host).equals('x.com');
assume(parsed.hostname).equals('x.com');
});
it('accepts + in the url', function () {
var url = 'http://x.y.com+a/b/c'
, parsed = parse(url);
assume(parsed.protocol).equals('http:');
assume(parsed.host).equals('x.y.com+a');
assume(parsed.hostname).equals('x.y.com+a');
assume(parsed.pathname).equals('/b/c');
});
describe('ip', function () {
// coap://
//
it('parses ipv6', function () {
var url = 'http://[1080:0:0:0:8:800:200C:417A]:61616/foo/bar?q=z'
, parsed = parse(url);
assume(parsed.port).equals('61616');
assume(parsed.query).equals('?q=z');
assume(parsed.protocol).equals('http:');
assume(parsed.hostname).equals('[1080:0:0:0:8:800:200c:417a]');
assume(parsed.pathname).equals('/foo/bar');
assume(parsed.href).equals('http://[1080:0:0:0:8:800:200c:417a]:61616/foo/bar?q=z');
});
it('parses ipv6 with auth', function () {
var url = 'http://user:password@[3ffe:2a00:100:7031::1]:8080'
, parsed = parse(url);
assume(parsed.username).equals('user');
assume(parsed.password).equals('password');
assume(parsed.host).equals('[3ffe:2a00:100:7031::1]:8080');
assume(parsed.hostname).equals('[3ffe:2a00:100:7031::1]');
assume(parsed.href).equals(url);
});
it('parses ipv4', function () {
var url = 'http://222.148.142.13:61616/foo/bar?q=z'
, parsed = parse(url);
assume(parsed.port).equals('61616');
assume(parsed.query).equals('?q=z');
assume(parsed.protocol).equals('http:');
assume(parsed.hostname).equals('222.148.142.13');
assume(parsed.pathname).equals('/foo/bar');
assume(parsed.href).equals(url);
});
});
describe('auth', function () {
it('does not lowercase the USER:PASS', function () {
var url = 'HTTP://USER:PASS@EXAMPLE.COM'
, parsed = parse(url);
assume(parsed.username).equals('USER');
assume(parsed.password).equals('PASS');
assume(parsed.protocol).equals('http:');
assume(parsed.host).equals('example.com');
assume(parsed.hostname).equals('example.com');
});
it('accepts @ in pathnames', function () {
var url = 'http://mt0.google.com/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s='
, parsed = parse(url);
assume(parsed.pathname).equals('/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=');
assume(parsed.username).equals('');
assume(parsed.password).equals('');
});
it('does not require passwords for auth', function () {
var url = 'http://user@www.example.com/'
, parsed = parse(url);
assume(parsed.password).equals('');
assume(parsed.pathname).equals('/');
assume(parsed.username).equals('user');
assume(parsed.protocol).equals('http:');
assume(parsed.hostname).equals('www.example.com');
});
});
it('accepts multiple ???', function () {

@@ -166,3 +262,4 @@ var url = 'http://mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=';

it('does not inherit auth from source object', function () {
var data = parse('/foo', parse('http://foo:bar@sub.example.com'));
var from = parse('http://foo:bar@sub.example.com')
, data = parse('/foo', from);

@@ -169,0 +266,0 @@ assume(data.port).equals('');

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