Skip to content

Commit

Permalink
fix: Fix querystring encoding (#1386)
Browse files Browse the repository at this point in the history
fix #1355
  • Loading branch information
jantimon committed Apr 1, 2020
1 parent ae85345 commit 4f48a39
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
27 changes: 26 additions & 1 deletion index.js
Expand Up @@ -939,10 +939,35 @@ 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
*
* However the query string must not be encoded:
*
* fo:demonstration-path/very fancy+name.js?path=/home?value=abc&value=def#zzz
* ^ ^ ^ ^ ^ ^ ^ ^^ ^ ^ ^ ^ ^
* | | | | | | | || | | | | |
* encoded | | encoded | | || | | | | |
* ignored ignored ignored ignored ignored
*
* @param {string} filePath
*/
urlencodePath (filePath) {
return filePath.split('/').map(encodeURIComponent).join('/');
// People use the filepath in quite unexpected ways.
// Try to extract the first querystring of the url:
//
// some+path/demo.html?value=abc?def
//
const queryStringStart = filePath.indexOf('?');
const urlPath = queryStringStart === -1 ? filePath : filePath.substr(0, queryStringStart);
const queryString = filePath.substr(urlPath.length);
// Encode all parts except '/' which are not part of the querystring:
const encodedUrlPath = urlPath.split('/').map(encodeURIComponent).join('/');
return encodedUrlPath + 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+file-name.js?path=/home?value=abc&value=def#zzz'
},
plugins: [new HtmlWebpackPlugin()]
}, ['<script src="fo%3Ao/very%20fancy%2Bfile-name.js?path=/home?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 4f48a39

Please sign in to comment.