Skip to content

Commit a4a0b37

Browse files
authored
Merge pull request #95 from dailyrandomphoto/fix-encode-once
fix(encodeURL): handle 'URI malformed' exception gracefully
2 parents 6155112 + 08eeff8 commit a4a0b37

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

lib/encode_url.js

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,35 @@
33
const { parse, format } = require('url');
44

55
function encodeURL(str) {
6-
if (parse(str).protocol) {
6+
const parsed = parse(str);
7+
if (parsed.protocol) {
78
const obj = Object.assign({}, {
8-
auth: parse(str).auth,
9-
protocol: parse(str).protocol,
10-
host: parse(str).host,
11-
pathname: encodeURI(decodeURI(parse(str).pathname))
9+
auth: parsed.auth,
10+
protocol: parsed.protocol,
11+
host: parsed.host,
12+
pathname: encodeURI(safeDecodeURI(parsed.pathname))
1213
});
1314

14-
if (parse(str).hash) {
15-
Object.assign(obj, { hash: encodeURI(decodeURI(parse(str).hash)) });
15+
if (parsed.hash) {
16+
Object.assign(obj, { hash: encodeURI(safeDecodeURI(parsed.hash)) });
1617
}
1718

18-
if (parse(str).search) {
19-
Object.assign(obj, { search: encodeURI(decodeURI(parse(str).search)) });
19+
if (parsed.search) {
20+
Object.assign(obj, { search: encodeURI(safeDecodeURI(parsed.search)) });
2021
}
2122

2223
return format(obj);
2324
}
2425

25-
return encodeURI(decodeURI(str));
26+
return encodeURI(safeDecodeURI(str));
27+
}
28+
29+
function safeDecodeURI(str) {
30+
try {
31+
return decodeURI(str);
32+
} catch (err) {
33+
return str;
34+
}
2635
}
2736

2837
module.exports = encodeURL;

test/encode_url.spec.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ describe('encodeURL', () => {
4545
encodeURL(content).should.eql('http://foo.com/bar?q%C3%BAery=b%C3%A1z');
4646
});
4747

48+
it('query contains %', () => {
49+
const content = 'http://foo.com/bar?query=%';
50+
encodeURL(content).should.eql('http://foo.com/bar?query=%25');
51+
});
52+
53+
it('path or query contains %', () => {
54+
const content = '/bar?query=%';
55+
encodeURL(content).should.eql('/bar?query=%25');
56+
});
57+
4858
it('multiple queries', () => {
4959
const content = 'http://foo.com/bar?query1=aáa&query2=aàa';
5060
encodeURL(content).should.eql('http://foo.com/bar?query1=a%C3%A1a&query2=a%C3%A0a');

0 commit comments

Comments
 (0)