Skip to content

Commit

Permalink
fix: Fix querystring encoding
Browse files Browse the repository at this point in the history
fix #1355
  • Loading branch information
jantimon committed Apr 1, 2020
1 parent 965dae6 commit 2f968ed
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
23 changes: 22 additions & 1 deletion index.js
Expand Up @@ -939,10 +939,31 @@ class HtmlWebpackPlugin {
* Encode each path component using `encodeURIComponent` as files can contain characters
* which needs special encoding in URLs like `+ `.
*
* Valid filesystem characters which need to be encoded for urls:
*
* # pound, % percent, & ampersand, { left curly bracket, } right curly bracket,
* \ back slash, < left angle bracket, > right angle bracket, * asterisk, ? question mark,
* blank spaces, $ dollar sign, ! exclamation point, ' single quotes, " double quotes,
* : colon, @ at sign, + plus sign, ` backtick, | pipe, = equal sign
*
* E.g.
* some/path?abc/xy+z/fancy.html?abc=foo#top
* ->
* some/path%3Fabc/xy%2Bz/fancy.html?abc=foo#top
*
* @param {string} filePath
*/
urlencodePath (filePath) {
return filePath.split('/').map(encodeURIComponent).join('/');
const urlParts = filePath.split('/');
// People use the filepath in quite unexpected ways.
// Try to extract the first querystring of the url:
//
// some?path/demo.html?value=abc?
// ^
const [lastPart, queryString] = urlParts[urlParts.length - 1].split('?', 2);
urlParts[urlParts.length - 1] = lastPart;
const encodedUrlPath = urlParts.map(encodeURIComponent).join('/');
return encodedUrlPath + (queryString ? `?${queryString}` : '');
}

/**
Expand Down
12 changes: 12 additions & 0 deletions spec/basic.spec.js
Expand Up @@ -116,6 +116,18 @@ describe('HtmlWebpackPlugin', () => {
}, [/<body>[\s]*<script src="foo\/very%20fancy%2Bname.js"><\/script>[\s]*<\/body>/], null, done);
});

it('properly encodes file names in emitted URIs but keeps the querystring', done => {
testHtmlPlugin({
mode: 'production',
entry: path.join(__dirname, 'fixtures/index.js'),
output: {
path: OUTPUT_DIR,
filename: 'fo?o/very fancy+name.js?value=abc&value=def#zzz'
},
plugins: [new HtmlWebpackPlugin()]
}, ['<script src="fo%3Fo/very%20fancy%2Bname.js?value=abc&value=def#zzz">'], null, done);
});

it('generates a default index.html file with multiple entry points', done => {
testHtmlPlugin({
mode: 'production',
Expand Down

0 comments on commit 2f968ed

Please sign in to comment.