Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,11 @@ module.exports = encodeUrl
var ENCODE_CHARS_REGEXP = /(?:[^\x21\x23-\x3B\x3D\x3F-\x5F\x61-\x7A\x7C\x7E]|%(?:[^0-9A-Fa-f]|[0-9A-Fa-f][^0-9A-Fa-f]|$))+/g

/**
* RegExp to match unmatched surrogate pair.
* RegExp to match surrogate pairs and unpaired surrogates.
* @private
*/

var UNMATCHED_SURROGATE_PAIR_REGEXP = /(^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF]([^\uDC00-\uDFFF]|$)/g

/**
* String to replace unmatched surrogate pair with.
* @private
*/

var UNMATCHED_SURROGATE_PAIR_REPLACE = '$1\uFFFD$2'
var SURROGATE_REGEXP = /([\uD800-\uDBFF][\uDC00-\uDFFF])|[\uD800-\uDFFF]/g

/**
* Encode a URL to a percent-encoded form, excluding already-encoded sequences.
Expand All @@ -55,6 +48,8 @@ var UNMATCHED_SURROGATE_PAIR_REPLACE = '$1\uFFFD$2'

function encodeUrl (url) {
return String(url)
.replace(UNMATCHED_SURROGATE_PAIR_REGEXP, UNMATCHED_SURROGATE_PAIR_REPLACE)
.replace(SURROGATE_REGEXP, function (match, pair) {
return pair || '\uFFFD'
})
.replace(ENCODE_CHARS_REGEXP, encodeURI)
}
12 changes: 12 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ describe('encodeUrl(url)', function () {
assert.strictEqual(encodeUrl('http://localhost/\uD83Dfoo\uDC7B <\uDC7B\uD83D>.html'), 'http://localhost/%EF%BF%BDfoo%EF%BF%BD%20%3C%EF%BF%BD%EF%BF%BD%3E.html')
})

it('should replace consecutive unpaired high surrogates', function () {
assert.strictEqual(encodeUrl('\uD800\uD800\uD800'), '%EF%BF%BD%EF%BF%BD%EF%BF%BD')
})

it('should replace consecutive unpaired low surrogates', function () {
assert.strictEqual(encodeUrl('\uDC00\uDC00\uDC00'), '%EF%BF%BD%EF%BF%BD%EF%BF%BD')
})

it('should preserve a valid pair next to unpaired surrogates', function () {
assert.strictEqual(encodeUrl('\uD800\uD83D\uDC7B\uDC00'), '%EF%BF%BD%F0%9F%91%BB%EF%BF%BD')
})

it('should encode at end of string', function () {
assert.strictEqual(encodeUrl('http://localhost/\uD83D'), 'http://localhost/%EF%BF%BD')
})
Expand Down