Skip to content

Commit

Permalink
utf8Sentinel => charsetSentinel
Browse files Browse the repository at this point in the history
  • Loading branch information
papandreou authored and ljharb committed Aug 2, 2018
1 parent da0929b commit 7bcf2dd
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 22 deletions.
16 changes: 8 additions & 8 deletions README.md
Expand Up @@ -162,28 +162,28 @@ or `application/x-www-form-urlencoded` body was *not* sent as
utf-8, eg. if the form had an `accept-charset` parameter or the
containing page had a different character set.

**qs** supports this mechanism via the `utf8Sentinel` option.
**qs** supports this mechanism via the `charsetSentinel` option.
If specified, the `utf8` parameter will be omitted from the
returned object. It will be used to switch to `iso-8859-1`/`utf-8`
mode depending on how the checkmark is encoded.

**Important**: When you specify both the `charset` option and the
`utf8Sentinel` option, the `charset` will be overridden when
`charsetSentinel` option, the `charset` will be overridden when
the request contains a `utf8` parameter from which the actual
charset can be deduced. In that sense the `charset` will behave
as the default charset rather than the authoritative charset.

```javascript
var detectedAsUtf8 = qs.parse('utf8=%E2%9C%93&a=%C3%B8', {
charset: 'iso-8859-1',
utf8Sentinel: true
charsetSentinel: true
});
assert.deepEqual(detectedAsUtf8, { a: 'ø' });

// Browsers encode the checkmark as ✓ when submitting as iso-8859-1:
var detectedAsIso8859_1 = qs.parse('utf8=%26%2310003%3B&a=%F8', {
charset: 'utf-8',
utf8Sentinel: true
charsetSentinel: true
});
assert.deepEqual(detectedAsIso8859_1, { a: 'ø' });
```
Expand All @@ -199,7 +199,7 @@ var detectedAsIso8859_1 = qs.parse('a=%26%239786%3B', {
assert.deepEqual(detectedAsIso8859_1, { a: '' });
```

It also works when the charset has been detected in `utf8Sentinel`
It also works when the charset has been detected in `charsetSentinel`
mode.

### Parsing Arrays
Expand Down Expand Up @@ -498,15 +498,15 @@ var numeric = qs.stringify({ a: '☺' }, { charset: 'iso-8859-1' });
assert.equal(numeric, 'a=%26%239786%3B');
```

You can use the `utf8Sentinel` option to announce the character by
You can use the `charsetSentinel` option to announce the character by
including an `utf8=✓` parameter with the proper encoding if the checkmark,
similar to what Ruby on Rails and others do when submitting forms.

```javascript
var sentinel = qs.stringify({ a: '' }, { utf8Sentinel: true });
var sentinel = qs.stringify({ a: '' }, { charsetSentinel: true });
assert.equal(sentinel, 'utf8=%E2%9C%93&a=%E2%98%BA');

var isoSentinel = qs.stringify({ a: 'æ' }, { utf8Sentinel: true, charset: 'iso-8859-1' });
var isoSentinel = qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'iso-8859-1' });
assert.equal(isoSentinel, 'utf8=%26%2310003%3B&a=%E6');
```

Expand Down
10 changes: 5 additions & 5 deletions lib/parse.js
Expand Up @@ -9,14 +9,14 @@ var defaults = {
allowPrototypes: false,
arrayLimit: 20,
charset: 'utf-8',
charsetSentinel: false,
decoder: utils.decode,
delimiter: '&',
depth: 5,
interpretNumericEntities: false,
parameterLimit: 1000,
plainObjects: false,
strictNullHandling: false,
utf8Sentinel: false
strictNullHandling: false
};

var interpretNumericEntities = function (str) {
Expand All @@ -34,7 +34,7 @@ var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('✓')

// These are the percent-encoded utf-8 octets representing a checkmark, indicating
// that the request actually is utf-8 encoded.
var utf8Sentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')
var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')

var parseValues = function parseQueryStringValues(str, options) {
var obj = {};
Expand All @@ -48,10 +48,10 @@ var parseValues = function parseQueryStringValues(str, options) {
if (charset !== undefined && charset !== 'utf-8' && charset !== 'iso-8859-1') {
throw new Error('The charset option must be either utf-8, iso-8859-1, or undefined');
}
if (options.utf8Sentinel) {
if (options.charsetSentinel) {
for (i = 0; i < parts.length; ++i) {
if (parts[i].indexOf('utf8=') === 0) {
if (parts[i] === utf8Sentinel) {
if (parts[i] === charsetSentinel) {
charset = 'utf-8';
} else if (parts[i] === isoSentinel) {
charset = 'iso-8859-1';
Expand Down
2 changes: 1 addition & 1 deletion lib/stringify.js
Expand Up @@ -215,7 +215,7 @@ module.exports = function (object, opts) {
var joined = keys.join(delimiter);
var prefix = options.addQueryPrefix === true ? '?' : '';

if (options.utf8Sentinel) {
if (options.charsetSentinel) {
if (charset === 'iso-8859-1') {
// encodeURIComponent('&#10003;'), the "numeric entity" representation of a checkmark
prefix += 'utf8=%26%2310003%3B&';
Expand Down
12 changes: 6 additions & 6 deletions test/parse.js
Expand Up @@ -595,32 +595,32 @@ test('parse()', function (t) {
var urlEncodedNumSmiley = '%26%239786%3B';

t.test('prefers an utf-8 charset specified by the utf8 sentinel to a default charset of iso-8859-1', function (st) {
st.deepEqual(qs.parse('utf8=' + urlEncodedCheckmarkInUtf8 + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { utf8Sentinel: true, charset: 'iso-8859-1' }), { ø: 'ø' });
st.deepEqual(qs.parse('utf8=' + urlEncodedCheckmarkInUtf8 + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true, charset: 'iso-8859-1' }), { ø: 'ø' });
st.end();
});

t.test('prefers an iso-8859-1 charset specified by the utf8 sentinel to a default charset of utf-8', function (st) {
st.deepEqual(qs.parse('utf8=' + urlEncodedNumCheckmark + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { utf8Sentinel: true, charset: 'utf-8' }), { 'ø': 'ø' });
st.deepEqual(qs.parse('utf8=' + urlEncodedNumCheckmark + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true, charset: 'utf-8' }), { 'ø': 'ø' });
st.end();
});

t.test('does not require the utf8 sentinel to be defined before the parameters whose decoding it affects', function (st) {
st.deepEqual(qs.parse('a=' + urlEncodedOSlashInUtf8 + '&utf8=' + urlEncodedNumCheckmark, { utf8Sentinel: true, charset: 'utf-8' }), { a: 'ø' });
st.deepEqual(qs.parse('a=' + urlEncodedOSlashInUtf8 + '&utf8=' + urlEncodedNumCheckmark, { charsetSentinel: true, charset: 'utf-8' }), { a: 'ø' });
st.end();
});

t.test('should ignore an utf8 sentinel with an unknown value', function (st) {
st.deepEqual(qs.parse('utf8=foo&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { utf8Sentinel: true, charset: 'utf-8' }), { ø: 'ø' });
st.deepEqual(qs.parse('utf8=foo&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true, charset: 'utf-8' }), { ø: 'ø' });
st.end();
});

t.test('uses the utf8 sentinel to switch to utf-8 when no default charset is given', function (st) {
st.deepEqual(qs.parse('utf8=' + urlEncodedCheckmarkInUtf8 + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { utf8Sentinel: true }), { ø: 'ø' });
st.deepEqual(qs.parse('utf8=' + urlEncodedCheckmarkInUtf8 + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true }), { ø: 'ø' });
st.end();
});

t.test('uses the utf8 sentinel to switch to iso-8859-1 when no default charset is given', function (st) {
st.deepEqual(qs.parse('utf8=' + urlEncodedNumCheckmark + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { utf8Sentinel: true }), { 'ø': 'ø' });
st.deepEqual(qs.parse('utf8=' + urlEncodedNumCheckmark + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true }), { 'ø': 'ø' });
st.end();
});

Expand Down
4 changes: 2 additions & 2 deletions test/stringify.js
Expand Up @@ -609,12 +609,12 @@ test('stringify()', function (t) {
});

t.test('adds the right sentinel when instructed to and the charset is utf-8', function (st) {
st.equal(qs.stringify({ a: 'æ' }, { utf8Sentinel: true, charset: 'utf-8' }), 'utf8=%E2%9C%93&a=%C3%A6');
st.equal(qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'utf-8' }), 'utf8=%E2%9C%93&a=%C3%A6');
st.end();
});

t.test('adds the right sentinel when instructed to and the charset is iso-8859-1', function (st) {
st.equal(qs.stringify({ a: 'æ' }, { utf8Sentinel: true, charset: 'iso-8859-1' }), 'utf8=%26%2310003%3B&a=%E6');
st.equal(qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'iso-8859-1' }), 'utf8=%26%2310003%3B&a=%E6');
st.end();
});

Expand Down

0 comments on commit 7bcf2dd

Please sign in to comment.