Skip to content

Commit

Permalink
[Fix] stringify: do not encode parens for RFC1738
Browse files Browse the repository at this point in the history
Fixes #390
  • Loading branch information
ljharb committed Jan 13, 2021
1 parent 9c60d53 commit 4e7a5a3
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 5 deletions.
10 changes: 7 additions & 3 deletions lib/stringify.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ var stringify = function stringify(
sort,
allowDots,
serializeDate,
format,
formatter,
encodeValuesOnly,
charset
Expand All @@ -85,16 +86,16 @@ var stringify = function stringify(

if (obj === null) {
if (strictNullHandling) {
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key') : prefix;
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix;
}

obj = '';
}

if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
if (encoder) {
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key');
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value'))];
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
}
return [formatter(prefix) + '=' + formatter(String(obj))];
}
Expand Down Expand Up @@ -139,6 +140,7 @@ var stringify = function stringify(
sort,
allowDots,
serializeDate,
format,
formatter,
encodeValuesOnly,
charset
Expand Down Expand Up @@ -186,6 +188,7 @@ var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder,
encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly,
filter: filter,
format: format,
formatter: formatter,
serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate,
skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls,
Expand Down Expand Up @@ -251,6 +254,7 @@ module.exports = function (object, opts) {
options.sort,
options.allowDots,
options.serializeDate,
options.format,
options.formatter,
options.encodeValuesOnly,
options.charset
Expand Down
5 changes: 4 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

var formats = require('./formats');

var has = Object.prototype.hasOwnProperty;
var isArray = Array.isArray;

Expand Down Expand Up @@ -120,7 +122,7 @@ var decode = function (str, decoder, charset) {
}
};

var encode = function encode(str, defaultEncoder, charset) {
var encode = function encode(str, defaultEncoder, charset, kind, format) {
// This code was originally written by Brian White (mscdex) for the io.js core querystring library.
// It has been adapted here for stricter adherence to RFC 3986
if (str.length === 0) {
Expand Down Expand Up @@ -152,6 +154,7 @@ var encode = function encode(str, defaultEncoder, charset) {
|| (c >= 0x30 && c <= 0x39) // 0-9
|| (c >= 0x41 && c <= 0x5A) // a-z
|| (c >= 0x61 && c <= 0x7A) // A-Z
|| (format === formats.RFC1738 && (c === 0x28 || c === 0x29)) // ( )
) {
out += string.charAt(i);
continue;
Expand Down
7 changes: 6 additions & 1 deletion test/stringify.js
Original file line number Diff line number Diff line change
Expand Up @@ -631,23 +631,28 @@ test('stringify()', function (t) {
st.end();
});

t.test('RFC 1738 spaces serialization', function (st) {
t.test('RFC 1738 serialization', function (st) {
st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC1738 }), 'a=b+c');
st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC1738 }), 'a+b=c+d');
st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }, { format: qs.formats.RFC1738 }), 'a+b=a+b');

st.equal(qs.stringify({ 'foo(ref)': 'bar' }, { format: qs.formats.RFC1738 }), 'foo(ref)=bar');

st.end();
});

t.test('RFC 3986 spaces serialization', function (st) {
st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC3986 }), 'a=b%20c');
st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC3986 }), 'a%20b=c%20d');
st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }, { format: qs.formats.RFC3986 }), 'a%20b=a%20b');

st.end();
});

t.test('Backward compatibility to RFC 3986', function (st) {
st.equal(qs.stringify({ a: 'b c' }), 'a=b%20c');
st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }), 'a%20b=a%20b');

st.end();
});

Expand Down

0 comments on commit 4e7a5a3

Please sign in to comment.