From c87ff2622b5833cf9be7e914caa2227afb2dd396 Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 6 May 2013 07:24:00 -0700 Subject: [PATCH] Apply D5832 to Phabricator Summary: Brings the Javelin change in D5832 into Phabricator. Test Plan: Hit a `/?&x` URI without hanging Safari. Reviewers: btrahan Reviewed By: btrahan CC: aran Differential Revision: https://secure.phabricator.com/D5833 --- src/__celerity_resource_map__.php | 44 +++++++++---------- webroot/rsrc/externals/javelin/lib/URI.js | 28 ++++++++---- .../externals/javelin/lib/__tests__/URI.js | 10 +++++ 3 files changed, 52 insertions(+), 30 deletions(-) diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 46934289e9..a84a14a316 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -2661,7 +2661,7 @@ celerity_register_resource_map(array( ), 'javelin-uri' => array( - 'uri' => '/res/0f8f2aef/rsrc/externals/javelin/lib/URI.js', + 'uri' => '/res/a1e5cbb3/rsrc/externals/javelin/lib/URI.js', 'type' => 'js', 'requires' => array( @@ -4176,7 +4176,7 @@ celerity_register_resource_map(array( 'uri' => '/res/pkg/f96657b8/diffusion.pkg.js', 'type' => 'js', ), - 'c9168ae3' => + '7d174323' => array( 'name' => 'javelin.pkg.js', 'symbols' => @@ -4201,7 +4201,7 @@ celerity_register_resource_map(array( 17 => 'javelin-typeahead-ondemand-source', 18 => 'javelin-tokenizer', ), - 'uri' => '/res/pkg/c9168ae3/javelin.pkg.js', + 'uri' => '/res/pkg/7d174323/javelin.pkg.js', 'type' => 'js', ), '6b1fccc6' => @@ -4261,7 +4261,7 @@ celerity_register_resource_map(array( 'global-drag-and-drop-css' => '55644450', 'inline-comment-summary-css' => '8aaacd1b', 'javelin-aphlict' => '26980a1c', - 'javelin-behavior' => 'c9168ae3', + 'javelin-behavior' => '7d174323', 'javelin-behavior-aphlict-dropdown' => '26980a1c', 'javelin-behavior-aphlict-listen' => '26980a1c', 'javelin-behavior-aphront-basic-tokenizer' => '26980a1c', @@ -4312,24 +4312,24 @@ celerity_register_resource_map(array( 'javelin-behavior-repository-crossreference' => '27c55b30', 'javelin-behavior-toggle-class' => '26980a1c', 'javelin-behavior-workflow' => '26980a1c', - 'javelin-dom' => 'c9168ae3', - 'javelin-event' => 'c9168ae3', - 'javelin-install' => 'c9168ae3', - 'javelin-json' => 'c9168ae3', - 'javelin-mask' => 'c9168ae3', - 'javelin-request' => 'c9168ae3', - 'javelin-resource' => 'c9168ae3', - 'javelin-stratcom' => 'c9168ae3', - 'javelin-tokenizer' => 'c9168ae3', - 'javelin-typeahead' => 'c9168ae3', - 'javelin-typeahead-normalizer' => 'c9168ae3', - 'javelin-typeahead-ondemand-source' => 'c9168ae3', - 'javelin-typeahead-preloaded-source' => 'c9168ae3', - 'javelin-typeahead-source' => 'c9168ae3', - 'javelin-uri' => 'c9168ae3', - 'javelin-util' => 'c9168ae3', - 'javelin-vector' => 'c9168ae3', - 'javelin-workflow' => 'c9168ae3', + 'javelin-dom' => '7d174323', + 'javelin-event' => '7d174323', + 'javelin-install' => '7d174323', + 'javelin-json' => '7d174323', + 'javelin-mask' => '7d174323', + 'javelin-request' => '7d174323', + 'javelin-resource' => '7d174323', + 'javelin-stratcom' => '7d174323', + 'javelin-tokenizer' => '7d174323', + 'javelin-typeahead' => '7d174323', + 'javelin-typeahead-normalizer' => '7d174323', + 'javelin-typeahead-ondemand-source' => '7d174323', + 'javelin-typeahead-preloaded-source' => '7d174323', + 'javelin-typeahead-source' => '7d174323', + 'javelin-uri' => '7d174323', + 'javelin-util' => '7d174323', + 'javelin-vector' => '7d174323', + 'javelin-workflow' => '7d174323', 'lightbox-attachment-css' => '55644450', 'maniphest-task-summary-css' => '6b1fccc6', 'maniphest-transaction-detail-css' => '6b1fccc6', diff --git a/webroot/rsrc/externals/javelin/lib/URI.js b/webroot/rsrc/externals/javelin/lib/URI.js index cca2d4e3bb..35e614fc7a 100644 --- a/webroot/rsrc/externals/javelin/lib/URI.js +++ b/webroot/rsrc/externals/javelin/lib/URI.js @@ -44,7 +44,6 @@ JX.$U = function(uri) { JX.install('URI', { statics : { _uriPattern : /(?:([^:\/?#]+):)?(?:\/\/([^:\/?#]*)(?::(\d*))?)?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/, - _queryPattern : /(?:^|&)([^&=]*)=?([^&]*)/g, /** * Convert a Javascript object into an HTTP query string. @@ -62,6 +61,10 @@ JX.install('URI', { } return kv_pairs.join('&'); + }, + + _decode : function(str) { + return decodeURIComponent(str.replace(/\+/g, ' ')); } }, @@ -94,14 +97,23 @@ JX.install('URI', { this.setPath(path.charAt(0) == '/' ? path : '/' + path); // parse the query data - if (query) { - var queryData = {}; - var data; - while ((data = JX.URI._queryPattern.exec(query)) != null) { - queryData[decodeURIComponent(data[1].replace(/\+/g, ' '))] = - decodeURIComponent(data[2].replace(/\+/g, ' ')); + if (query && query.length) { + var dict = {}; + var parts = query.split('&'); + for (var ii = 0; ii < parts.length; ii++) { + var part = parts[ii]; + if (!part.length) { + continue; + } + var pieces = part.split('='); + var name = pieces[0]; + if (!name.length) { + continue; + } + var value = pieces.slice(1).join('=') || ''; + dict[JX.URI._decode(name)] = JX.URI._decode(value); } - this.setQueryParams(queryData); + this.setQueryParams(dict); } } }, diff --git a/webroot/rsrc/externals/javelin/lib/__tests__/URI.js b/webroot/rsrc/externals/javelin/lib/__tests__/URI.js index 3dbaa3f968..56639a161f 100644 --- a/webroot/rsrc/externals/javelin/lib/__tests__/URI.js +++ b/webroot/rsrc/externals/javelin/lib/__tests__/URI.js @@ -289,5 +289,15 @@ describe('Javelin URI', function() { expect(uri2.getQueryParams()).not.toEqual({'key' : 'value'}); }); + it('should not loop indefinitely when parsing empty params', function() { + expect(JX.$U('/?&key=value').getQueryParams()).toEqual({'key' : 'value'}); + expect(JX.$U('/?&&&key=value').getQueryParams()).toEqual({'key' : 'value'}); + expect(JX.$U('/?&&').getQueryParams()).toEqual({}); + }); + + it('should parse values with =', function() { + expect(JX.$U('/?x=1=1').getQueryParams()).toEqual({'x' : '1=1'}); + }); + });