diff --git a/packages/@vue/cli-plugin-pwa/__tests__/pwaGenerator.spec.js b/packages/@vue/cli-plugin-pwa/__tests__/pwaGenerator.spec.js index 222f5f0c7e..b8c2ab26b5 100644 --- a/packages/@vue/cli-plugin-pwa/__tests__/pwaGenerator.spec.js +++ b/packages/@vue/cli-plugin-pwa/__tests__/pwaGenerator.spec.js @@ -1,4 +1,8 @@ const generateWithPlugin = require('@vue/cli-test-utils/generateWithPlugin') +const HtmlPwaPlugin = require('../lib/HtmlPwaPlugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const { performance } = require('perf_hooks') +global.performance = performance test('inject import statement for service worker', async () => { const { files } = await generateWithPlugin([ @@ -38,3 +42,42 @@ test('inject import statement for service worker (with TS)', async () => { expect(files['src/main.ts']).toMatch(`import './registerServiceWorker'`) }) + +test('ReDos test', async () => { + HtmlWebpackPlugin.getHooks = () => ({ + beforeEmit: { + tapAsync: (id, handler) => { + const hugeHtml = ' {}) + } + }, + alterAssetTagGroups: { + tapAsync: () => {} + } + }) + const plugin = new HtmlPwaPlugin() + const fakeCompiler = { + options: { output: { publicPath: '/' } }, + hooks: { + compilation: { + tap: (_id, cb) => { + const fakeCompilation = { + hooks: { + processAssets: { + tap: (_opts, fn) => {} + } + } + } + cb(fakeCompilation) + } + } + } + } + const startTime = performance.now() + plugin.apply(fakeCompiler) + const endTime = performance.now() + const timeTaken = endTime - startTime + console.log(`time taken: ${timeTaken.toFixed(3)} ms`) + expect(timeTaken).toBeLessThan(3000) +}, 3000) diff --git a/packages/@vue/cli-plugin-pwa/lib/HtmlPwaPlugin.js b/packages/@vue/cli-plugin-pwa/lib/HtmlPwaPlugin.js index ba86f2a23b..2dc18dc06a 100644 --- a/packages/@vue/cli-plugin-pwa/lib/HtmlPwaPlugin.js +++ b/packages/@vue/cli-plugin-pwa/lib/HtmlPwaPlugin.js @@ -64,7 +64,7 @@ module.exports = class HtmlPwaPlugin { compiler.hooks.compilation.tap(ID, compilation => { HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(ID, (data, cb) => { // wrap favicon in the base template with IE only comment - data.html = data.html.replace(/]+>/, '') + data.html = data.html.replace(/]+>/, '') cb(null, data) })