From f57c78c673eb8dd4b892b05a071145b2d02b3362 Mon Sep 17 00:00:00 2001 From: "Michael A. Gonzalez" Date: Tue, 5 Mar 2019 22:47:22 -0500 Subject: [PATCH] Trailing = in parameters were being split Some of our GraphQL IDs had `=` in their value, therefore splitting on `=` creates issues - unless we split by the 1st occurence. For example: `?testCode_In=VGVzdENvZGVOb2RlOjQ=` will be parsed as: `{testCode_In: "VGVzdENvZGVOb2RlOjQ"}`. This leads to confusion and inaccurate search terms. --- index.js | 3 ++- package.json | 1 + test/parse-url.js | 5 +++++ test/parse.js | 5 +++++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 58744d36..1267c266 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ 'use strict'; const strictUriEncode = require('strict-uri-encode'); const decodeComponent = require('decode-uri-component'); +const splitOnFirst = require('split-on-first'); function encoderForArrayFormat(options) { switch (options.arrayFormat) { @@ -150,7 +151,7 @@ function parse(input, options) { } for (const param of input.split('&')) { - let [key, value] = param.replace(/\+/g, ' ').split('='); + let [key, value] = splitOnFirst(param.replace(/\+/g, ' '), '='); // Missing `=` should be `null`: // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters diff --git a/package.json b/package.json index 2638d5b7..fa52c7ff 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "ava": "^1.2.1", "deep-equal": "^1.0.1", "fast-check": "^1.5.0", + "split-on-first": "^1.0.0", "tsd-check": "^0.3.0", "xo": "^0.24.0" } diff --git a/test/parse-url.js b/test/parse-url.js index 239427e8..477d6061 100644 --- a/test/parse-url.js +++ b/test/parse-url.js @@ -13,6 +13,11 @@ test('handles strings not containing query string', t => { t.deepEqual(m.parseUrl(''), {url: '', query: {}}); }); +test('handles strings with query string that contain =', t => { + t.deepEqual(m.parseUrl('https://foo.bar?foo=baz=bar&foo=baz#top'), {url: 'https://foo.bar', query: {foo: ['baz=bar', 'baz']}}); + t.deepEqual(m.parseUrl('https://foo.bar?foo=bar=&foo=baz='), {url: 'https://foo.bar', query: {foo: ['bar=', 'baz=']}}); +}); + test('throws for invalid values', t => { t.throws(() => { m.parseUrl(null); diff --git a/test/parse.js b/test/parse.js index 999cff83..a034b89b 100644 --- a/test/parse.js +++ b/test/parse.js @@ -122,6 +122,11 @@ test('query strings having indexed arrays and format option as `index`', t => { }), {foo: ['bar', 'baz']}); }); +test('query strings having = within parameters (i.e. GraphQL IDs)', t => { + t.deepEqual(m.parse('foo=bar=&foo=ba=z=', { + }), {foo: ['bar=', 'ba=z=']}); +}); + test('query strings having ordered index arrays and format option as `index`', t => { t.deepEqual(m.parse('foo[1]=bar&foo[0]=baz&foo[3]=one&foo[2]=two', { arrayFormat: 'index'