From a6abd47607b4fe0ec8ba52bc4f866150e2536394 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Thu, 8 May 2025 09:34:19 -0700 Subject: [PATCH 1/2] devops: get rid of fd-slicer dependency and esbuild plugin hack * Bumped yauzl 2.10.0 -> 3.2.0 as https://github.com/thejoshwolfe/yauzl/issues/114 is fixed in v3 and yauzl does not depend on fd-slicer any more. * Vendored in extract-zip as it still depends on yauzl 2.10.0. This can be reverted if https://github.com/max-mapper/extract-zip/pull/146 is merged. --- .../playwright-core/ThirdPartyNotices.txt | 176 ++++++---------- packages/playwright-core/bundles/zip/build.js | 18 -- .../bundles/zip/package-lock.json | 139 +++++------- .../playwright-core/bundles/zip/package.json | 6 +- .../zip/src/third_party/extract-zip.d.ts | 56 +++++ .../zip/src/third_party/extract-zip.js | 199 ++++++++++++++++++ .../bundles/zip/src/zipBundleImpl.ts | 2 +- packages/playwright-core/src/zipBundle.ts | 2 +- tests/library/browsercontext-har.spec.ts | 2 +- tests/playwright-test/reporter-blob.spec.ts | 2 +- 10 files changed, 375 insertions(+), 227 deletions(-) create mode 100644 packages/playwright-core/bundles/zip/src/third_party/extract-zip.d.ts create mode 100644 packages/playwright-core/bundles/zip/src/third_party/extract-zip.js diff --git a/packages/playwright-core/ThirdPartyNotices.txt b/packages/playwright-core/ThirdPartyNotices.txt index 420d698fa512a..744720e00d113 100644 --- a/packages/playwright-core/ThirdPartyNotices.txt +++ b/packages/playwright-core/ThirdPartyNotices.txt @@ -4,8 +4,6 @@ THIRD-PARTY SOFTWARE NOTICES AND INFORMATION This project incorporates components from the projects listed below. The original copyright notices and the licenses under which Microsoft received such components are set forth below. Microsoft reserves all rights not expressly granted herein, whether by implication, estoppel or otherwise. -- @types/node@17.0.24 (https://github.com/DefinitelyTyped/DefinitelyTyped) -- @types/yauzl@2.10.0 (https://github.com/DefinitelyTyped/DefinitelyTyped) - agent-base@6.0.2 (https://github.com/TooTallNate/node-agent-base) - balanced-match@1.0.2 (https://github.com/juliangruber/balanced-match) - brace-expansion@1.1.11 (https://github.com/juliangruber/brace-expansion) @@ -15,12 +13,11 @@ This project incorporates components from the projects listed below. The origina - commander@8.3.0 (https://github.com/tj/commander.js) - concat-map@0.0.1 (https://github.com/substack/node-concat-map) - debug@4.3.4 (https://github.com/debug-js/debug) +- debug@4.4.0 (https://github.com/debug-js/debug) - define-lazy-prop@2.0.0 (https://github.com/sindresorhus/define-lazy-prop) - diff@7.0.0 (https://github.com/kpdecker/jsdiff) - dotenv@16.4.5 (https://github.com/motdotla/dotenv) - end-of-stream@1.4.4 (https://github.com/mafintosh/end-of-stream) -- extract-zip@2.0.1 (https://github.com/maxogden/extract-zip) -- fd-slicer@1.1.0 (https://github.com/andrewrk/node-fd-slicer) - get-stream@5.2.0 (https://github.com/sindresorhus/get-stream) - graceful-fs@4.2.10 (https://github.com/isaacs/node-graceful-fs) - https-proxy-agent@5.0.1 (https://github.com/TooTallNate/node-https-proxy-agent) @@ -32,13 +29,14 @@ This project incorporates components from the projects listed below. The origina - mime@3.0.0 (https://github.com/broofa/mime) - minimatch@3.1.2 (https://github.com/isaacs/minimatch) - ms@2.1.2 (https://github.com/zeit/ms) +- ms@2.1.3 (https://github.com/vercel/ms) - once@1.4.0 (https://github.com/isaacs/once) - open@8.4.0 (https://github.com/sindresorhus/open) - pend@1.2.0 (https://github.com/andrewrk/node-pend) - pngjs@6.0.0 (https://github.com/lukeapage/pngjs) - progress@2.0.3 (https://github.com/visionmedia/node-progress) - proxy-from-env@1.1.0 (https://github.com/Rob--W/proxy-from-env) -- pump@3.0.0 (https://github.com/mafintosh/pump) +- pump@3.0.2 (https://github.com/mafintosh/pump) - retry@0.12.0 (https://github.com/tim-kos/node-retry) - signal-exit@3.0.7 (https://github.com/tapjs/signal-exit) - smart-buffer@4.2.0 (https://github.com/JoshGlazebrook/smart-buffer) @@ -48,61 +46,9 @@ This project incorporates components from the projects listed below. The origina - wrappy@1.0.2 (https://github.com/npm/wrappy) - ws@8.17.1 (https://github.com/websockets/ws) - yaml@2.6.0 (https://github.com/eemeli/yaml) -- yauzl@2.10.0 (https://github.com/thejoshwolfe/yauzl) +- yauzl@3.2.0 (https://github.com/thejoshwolfe/yauzl) - yazl@2.5.1 (https://github.com/thejoshwolfe/yazl) -%% @types/node@17.0.24 NOTICES AND INFORMATION BEGIN HERE -========================================= -MIT License - - Copyright (c) Microsoft Corporation. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE -========================================= -END OF @types/node@17.0.24 AND INFORMATION - -%% @types/yauzl@2.10.0 NOTICES AND INFORMATION BEGIN HERE -========================================= -MIT License - - Copyright (c) Microsoft Corporation. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE -========================================= -END OF @types/yauzl@2.10.0 AND INFORMATION - %% agent-base@6.0.2 NOTICES AND INFORMATION BEGIN HERE ========================================= agent-base @@ -459,6 +405,30 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ========================================= END OF debug@4.3.4 AND INFORMATION +%% debug@4.4.0 NOTICES AND INFORMATION BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) 2014-2017 TJ Holowaychuk +Copyright (c) 2018-2021 Josh Junon + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the 'Software'), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF debug@4.4.0 AND INFORMATION + %% define-lazy-prop@2.0.0 NOTICES AND INFORMATION BEGIN HERE ========================================= MIT License @@ -561,60 +531,6 @@ THE SOFTWARE. ========================================= END OF end-of-stream@1.4.4 AND INFORMATION -%% extract-zip@2.0.1 NOTICES AND INFORMATION BEGIN HERE -========================================= -Copyright (c) 2014 Max Ogden and other contributors -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -========================================= -END OF extract-zip@2.0.1 AND INFORMATION - -%% fd-slicer@1.1.0 NOTICES AND INFORMATION BEGIN HERE -========================================= -Copyright (c) 2014 Andrew Kelley - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation files -(the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of the Software, -and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -========================================= -END OF fd-slicer@1.1.0 AND INFORMATION - %% get-stream@5.2.0 NOTICES AND INFORMATION BEGIN HERE ========================================= MIT License @@ -990,6 +906,32 @@ SOFTWARE. ========================================= END OF ms@2.1.2 AND INFORMATION +%% ms@2.1.3 NOTICES AND INFORMATION BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2020 Vercel, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +========================================= +END OF ms@2.1.3 AND INFORMATION + %% once@1.4.0 NOTICES AND INFORMATION BEGIN HERE ========================================= The ISC License @@ -1129,7 +1071,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ========================================= END OF proxy-from-env@1.1.0 AND INFORMATION -%% pump@3.0.0 NOTICES AND INFORMATION BEGIN HERE +%% pump@3.0.2 NOTICES AND INFORMATION BEGIN HERE ========================================= The MIT License (MIT) @@ -1153,7 +1095,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ========================================= -END OF pump@3.0.0 AND INFORMATION +END OF pump@3.0.2 AND INFORMATION %% retry@0.12.0 NOTICES AND INFORMATION BEGIN HERE ========================================= @@ -1501,7 +1443,7 @@ THIS SOFTWARE. ========================================= END OF yaml@2.6.0 AND INFORMATION -%% yauzl@2.10.0 NOTICES AND INFORMATION BEGIN HERE +%% yauzl@3.2.0 NOTICES AND INFORMATION BEGIN HERE ========================================= The MIT License (MIT) @@ -1525,7 +1467,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ========================================= -END OF yauzl@2.10.0 AND INFORMATION +END OF yauzl@3.2.0 AND INFORMATION %% yazl@2.5.1 NOTICES AND INFORMATION BEGIN HERE ========================================= @@ -1555,6 +1497,6 @@ END OF yazl@2.5.1 AND INFORMATION SUMMARY BEGIN HERE ========================================= -Total Packages: 46 +Total Packages: 44 ========================================= END OF SUMMARY \ No newline at end of file diff --git a/packages/playwright-core/bundles/zip/build.js b/packages/playwright-core/bundles/zip/build.js index 114ed463a917c..6efadad71c11d 100644 --- a/packages/playwright-core/bundles/zip/build.js +++ b/packages/playwright-core/bundles/zip/build.js @@ -16,31 +16,13 @@ // @ts-check const path = require('path'); -const fs = require('fs'); const esbuild = require('esbuild'); -// Can be removed once https://github.com/thejoshwolfe/yauzl/issues/114 is fixed. -/** @type{import('esbuild').Plugin} */ -let patchFdSlicerToHideBufferDeprecationWarning = { - name: 'patch-fd-slicer-deprecation', - setup(build) { - build.onResolve({ filter: /^fd-slicer$/ }, () => { - const originalPath = require.resolve('fd-slicer'); - const patchedPath = path.join(path.dirname(originalPath), path.basename(originalPath, '.js') + '.pw-patched.js'); - let sourceFileContent = fs.readFileSync(originalPath, 'utf8') - sourceFileContent = sourceFileContent.replace(/new Buffer\(toRead\)/g, 'Buffer.alloc(toRead)'); - fs.writeFileSync(patchedPath, sourceFileContent); - return { path: patchedPath } - }); - }, -}; - (async () => { const ctx = await esbuild.context({ entryPoints: [path.join(__dirname, 'src/zipBundleImpl.ts')], bundle: true, outdir: path.join(__dirname, '../../lib'), - plugins: [patchFdSlicerToHideBufferDeprecationWarning], format: 'cjs', platform: 'node', target: 'ES2019', diff --git a/packages/playwright-core/bundles/zip/package-lock.json b/packages/playwright-core/bundles/zip/package-lock.json index 8476d11c199ae..19eaf81c63825 100644 --- a/packages/playwright-core/bundles/zip/package-lock.json +++ b/packages/playwright-core/bundles/zip/package-lock.json @@ -8,8 +8,9 @@ "name": "zip-bundle", "version": "0.0.1", "dependencies": { - "extract-zip": "2.0.1", - "yauzl": "2.10.0", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "3.2.0", "yazl": "2.5.1" }, "devDependencies": { @@ -21,13 +22,13 @@ "version": "17.0.24", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==", - "devOptional": true + "dev": true }, "node_modules/@types/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "devOptional": true, + "dev": true, "dependencies": { "@types/node": "*" } @@ -50,11 +51,12 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -69,41 +71,16 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "license": "MIT", "dependencies": { "once": "^1.4.0" } }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "license": "MIT", "dependencies": { "pump": "^3.0.0" }, @@ -115,14 +92,16 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -130,12 +109,14 @@ "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "license": "MIT" }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -144,15 +125,20 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" }, "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.0.tgz", + "integrity": "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==", + "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" + "pend": "~1.2.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/yazl": { @@ -169,13 +155,13 @@ "version": "17.0.24", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==", - "devOptional": true + "dev": true }, "@types/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "devOptional": true, + "dev": true, "requires": { "@types/node": "*" } @@ -195,11 +181,11 @@ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" }, "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "requires": { - "ms": "2.1.2" + "ms": "^2.1.3" } }, "end-of-stream": { @@ -210,25 +196,6 @@ "once": "^1.4.0" } }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "requires": { - "pend": "~1.2.0" - } - }, "get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -238,14 +205,14 @@ } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } @@ -253,12 +220,12 @@ "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -267,15 +234,15 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.0.tgz", + "integrity": "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==", "requires": { "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" + "pend": "~1.2.0" } }, "yazl": { diff --git a/packages/playwright-core/bundles/zip/package.json b/packages/playwright-core/bundles/zip/package.json index 0d9650d2841be..64f75f719596e 100644 --- a/packages/playwright-core/bundles/zip/package.json +++ b/packages/playwright-core/bundles/zip/package.json @@ -9,8 +9,10 @@ "generate-license": "node ../../../../utils/generate_third_party_notice.js" }, "dependencies": { - "extract-zip": "2.0.1", - "yauzl": "2.10.0", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + + "yauzl": "3.2.0", "yazl": "2.5.1" }, "devDependencies": { diff --git a/packages/playwright-core/bundles/zip/src/third_party/extract-zip.d.ts b/packages/playwright-core/bundles/zip/src/third_party/extract-zip.d.ts new file mode 100644 index 0000000000000..9c15913775bb8 --- /dev/null +++ b/packages/playwright-core/bundles/zip/src/third_party/extract-zip.d.ts @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2014 Max Ogden and other contributors + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// Based on the type definitions for extract-zip 1.6 +// Definitions by: Mizunashi Mana +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/e69b58e/types/extract-zip/index.d.ts + +import { Entry, ZipFile } from 'yauzl'; + +declare namespace extract { + interface Options { + /** The path to the directory where the extracted files are written */ + dir: string; + /** Directory Mode (permissions), defaults to `0o755` */ + defaultDirMode?: number; + /** File Mode (permissions), defaults to `0o644` */ + defaultFileMode?: number; + /** + * If present, will be called with (entry, zipfile), + * entry is every entry from the zip file forwarded + * from the entry event from yauzl. zipfile is the + * yauzl instance + */ + onEntry?: (entry: Entry, zipfile: ZipFile) => void; + } +} + +declare function extract( + zipPath: string, + opts: extract.Options, +): Promise; + +export = extract; diff --git a/packages/playwright-core/bundles/zip/src/third_party/extract-zip.js b/packages/playwright-core/bundles/zip/src/third_party/extract-zip.js new file mode 100644 index 0000000000000..0dd76be59559e --- /dev/null +++ b/packages/playwright-core/bundles/zip/src/third_party/extract-zip.js @@ -0,0 +1,199 @@ +/** + * Copyright (c) 2014 Max Ogden and other contributors + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +const debug = require('debug')('extract-zip') +// eslint-disable-next-line node/no-unsupported-features/node-builtins +const { createWriteStream, promises: fs } = require('fs') +const getStream = require('get-stream') +const path = require('path') +const { promisify } = require('util') +const stream = require('stream') +const yauzl = require('yauzl') + +const openZip = promisify(yauzl.open) +const pipeline = promisify(stream.pipeline) + +class Extractor { + constructor (zipPath, opts) { + this.zipPath = zipPath + this.opts = opts + } + + async extract () { + debug('opening', this.zipPath, 'with opts', this.opts) + + this.zipfile = await openZip(this.zipPath, { lazyEntries: true }) + this.canceled = false + + return new Promise((resolve, reject) => { + this.zipfile.on('error', err => { + this.canceled = true + reject(err) + }) + this.zipfile.readEntry() + + this.zipfile.on('close', () => { + if (!this.canceled) { + debug('zip extraction complete') + resolve() + } + }) + + this.zipfile.on('entry', async entry => { + /* istanbul ignore if */ + if (this.canceled) { + debug('skipping entry', entry.fileName, { cancelled: this.canceled }) + return + } + + debug('zipfile entry', entry.fileName) + + if (entry.fileName.startsWith('__MACOSX/')) { + this.zipfile.readEntry() + return + } + + const destDir = path.dirname(path.join(this.opts.dir, entry.fileName)) + + try { + await fs.mkdir(destDir, { recursive: true }) + + const canonicalDestDir = await fs.realpath(destDir) + const relativeDestDir = path.relative(this.opts.dir, canonicalDestDir) + + if (relativeDestDir.split(path.sep).includes('..')) { + throw new Error(`Out of bound path "${canonicalDestDir}" found while processing file ${entry.fileName}`) + } + + await this.extractEntry(entry) + debug('finished processing', entry.fileName) + this.zipfile.readEntry() + } catch (err) { + this.canceled = true + this.zipfile.close() + reject(err) + } + }) + }) + } + + async extractEntry (entry) { + /* istanbul ignore if */ + if (this.canceled) { + debug('skipping entry extraction', entry.fileName, { cancelled: this.canceled }) + return + } + + if (this.opts.onEntry) { + this.opts.onEntry(entry, this.zipfile) + } + + const dest = path.join(this.opts.dir, entry.fileName) + + // convert external file attr int into a fs stat mode int + const mode = (entry.externalFileAttributes >> 16) & 0xFFFF + // check if it's a symlink or dir (using stat mode constants) + const IFMT = 61440 + const IFDIR = 16384 + const IFLNK = 40960 + const symlink = (mode & IFMT) === IFLNK + let isDir = (mode & IFMT) === IFDIR + + // Failsafe, borrowed from jsZip + if (!isDir && entry.fileName.endsWith('/')) { + isDir = true + } + + // check for windows weird way of specifying a directory + // https://github.com/maxogden/extract-zip/issues/13#issuecomment-154494566 + const madeBy = entry.versionMadeBy >> 8 + if (!isDir) isDir = (madeBy === 0 && entry.externalFileAttributes === 16) + + debug('extracting entry', { filename: entry.fileName, isDir: isDir, isSymlink: symlink }) + + const procMode = this.getExtractedMode(mode, isDir) & 0o777 + + // always ensure folders are created + const destDir = isDir ? dest : path.dirname(dest) + + const mkdirOptions = { recursive: true } + if (isDir) { + mkdirOptions.mode = procMode + } + debug('mkdir', { dir: destDir, ...mkdirOptions }) + await fs.mkdir(destDir, mkdirOptions) + if (isDir) return + + debug('opening read stream', dest) + const readStream = await promisify(this.zipfile.openReadStream.bind(this.zipfile))(entry) + + if (symlink) { + const link = await getStream(readStream) + debug('creating symlink', link, dest) + await fs.symlink(link, dest) + } else { + await pipeline(readStream, createWriteStream(dest, { mode: procMode })) + } + } + + getExtractedMode (entryMode, isDir) { + let mode = entryMode + // Set defaults, if necessary + if (mode === 0) { + if (isDir) { + if (this.opts.defaultDirMode) { + mode = parseInt(this.opts.defaultDirMode, 10) + } + + if (!mode) { + mode = 0o755 + } + } else { + if (this.opts.defaultFileMode) { + mode = parseInt(this.opts.defaultFileMode, 10) + } + + if (!mode) { + mode = 0o644 + } + } + } + + return mode + } +} + +module.exports = async function (zipPath, opts) { + debug('creating target directory', opts.dir) + + if (!path.isAbsolute(opts.dir)) { + throw new Error('Target directory is expected to be absolute') + } + + await fs.mkdir(opts.dir, { recursive: true }) + opts.dir = await fs.realpath(opts.dir) + return new Extractor(zipPath, opts).extract() +} diff --git a/packages/playwright-core/bundles/zip/src/zipBundleImpl.ts b/packages/playwright-core/bundles/zip/src/zipBundleImpl.ts index b69e1a168a71a..a26529342792f 100644 --- a/packages/playwright-core/bundles/zip/src/zipBundleImpl.ts +++ b/packages/playwright-core/bundles/zip/src/zipBundleImpl.ts @@ -16,5 +16,5 @@ export * as yazl from 'yazl'; export * as yauzl from 'yauzl'; -import extractZip from 'extract-zip'; +const extractZip = require('./third_party/extract-zip'); export const extract = extractZip; diff --git a/packages/playwright-core/src/zipBundle.ts b/packages/playwright-core/src/zipBundle.ts index 22569758b688b..093a51698fc68 100644 --- a/packages/playwright-core/src/zipBundle.ts +++ b/packages/playwright-core/src/zipBundle.ts @@ -18,4 +18,4 @@ export const yazl: typeof import('../bundles/zip/node_modules/@types/yazl') = re export type { ZipFile } from '../bundles/zip/node_modules/@types/yazl'; export const yauzl: typeof import('../bundles/zip/node_modules/@types/yauzl') = require('./zipBundleImpl').yauzl; export type { Entry, ZipFile as UnzipFile } from '../bundles/zip/node_modules/@types/yauzl'; -export const extract: typeof import('../bundles/zip/node_modules/extract-zip') = require('./zipBundleImpl').extract; +export const extract: typeof import('../bundles/zip/src/third_party/extract-zip.d.ts') = require('./zipBundleImpl').extract; diff --git a/tests/library/browsercontext-har.spec.ts b/tests/library/browsercontext-har.spec.ts index 796a37426a396..6e64045902508 100644 --- a/tests/library/browsercontext-har.spec.ts +++ b/tests/library/browsercontext-har.spec.ts @@ -17,7 +17,7 @@ import { browserTest as it, expect } from '../config/browserTest'; import fs from 'fs'; import path from 'path'; -import extractZip from '../../packages/playwright-core/bundles/zip/node_modules/extract-zip'; +import extractZip from '../../packages/playwright-core/bundles/zip/src/third_party/extract-zip'; it('should context.routeFromHAR, matching the method and following redirects', async ({ context, asset }) => { const path = asset('har-fulfill.har'); diff --git a/tests/playwright-test/reporter-blob.spec.ts b/tests/playwright-test/reporter-blob.spec.ts index 504025f7de845..a4de72e58fd24 100644 --- a/tests/playwright-test/reporter-blob.spec.ts +++ b/tests/playwright-test/reporter-blob.spec.ts @@ -21,7 +21,7 @@ import url from 'url'; import type { HttpServer } from '../../packages/playwright-core/lib/server/utils/httpServer'; import { startHtmlReportServer } from '../../packages/playwright/lib/reporters/html'; import { expect as baseExpect, test as baseTest, stripAnsi } from './playwright-test-fixtures'; -import extractZip from '../../packages/playwright-core/bundles/zip/node_modules/extract-zip'; +import extractZip from '../../packages/playwright-core/bundles/zip/src/third_party/extract-zip'; import * as yazl from '../../packages/playwright-core/bundles/zip/node_modules/yazl'; import { getUserAgent } from '../../packages/playwright-core/lib/server/utils/userAgent'; import { Readable } from 'stream'; From cd13a20d73104a4a524f1620dafa2d5cbe6fb398 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Thu, 8 May 2025 10:24:30 -0700 Subject: [PATCH 2/2] exclued extract-zip from eslint --- eslint.config.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/eslint.config.mjs b/eslint.config.mjs index a1627868865d2..7a8933e5301de 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -45,6 +45,7 @@ const ignores = [ "output/", "**/playwright-report/", "packages/*/lib/", + "packages/playwright-core/bundles/zip/src/third_party/", "packages/playwright-core/src/generated/*", "packages/playwright-core/src/third_party/", "packages/playwright-core/types/*",