Skip to content

Commit 8f94ae8

Browse files
authored
fix(utils/tar): index access while match is null (#7555) (#7556)
Details explained in issue #7555 Closes #7555
1 parent 2d1d8d0 commit 8f94ae8

File tree

2 files changed

+84
-3
lines changed

2 files changed

+84
-3
lines changed

lib/utils/tar.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const getContents = async (manifest, tarball) => {
5959
totalEntries++
6060
totalEntrySize += entry.size
6161
const p = entry.path
62-
if (p.startsWith('package/node_modules/')) {
62+
if (p.startsWith('package/node_modules/') && p !== 'package/node_modules/') {
6363
const name = p.match(/^package\/node_modules\/((?:@[^/]+\/)?[^/]+)/)[1]
6464
bundled.add(name)
6565
}
@@ -72,7 +72,7 @@ const getContents = async (manifest, tarball) => {
7272
})
7373
stream.end(tarball)
7474

75-
const integrity = await ssri.fromData(tarball, {
75+
const integrity = ssri.fromData(tarball, {
7676
algorithms: ['sha1', 'sha512'],
7777
})
7878

test/lib/utils/tar.js

+82-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
const t = require('tap')
2+
const tar = require('tar')
23
const pack = require('libnpmpack')
34
const ssri = require('ssri')
5+
const { readFile } = require('fs/promises')
46
const tmock = require('../../fixtures/tmock')
57
const { cleanZlib } = require('../../fixtures/clean-snapshot')
68

@@ -106,7 +108,7 @@ t.test('should log tarball contents with unicode', async (t) => {
106108
t.end()
107109
})
108110

109-
t.test('should getContents of a tarball', async (t) => {
111+
t.test('should getContents of a tarball with only a package.json', async (t) => {
110112
const testDir = t.testdir({
111113
'package.json': JSON.stringify({
112114
name: 'my-cool-pkg',
@@ -142,3 +144,82 @@ t.test('should getContents of a tarball', async (t) => {
142144
}, 'contents are correct')
143145
t.end()
144146
})
147+
148+
t.test('should getContents of a tarball with a node_modules directory included', async (t) => {
149+
const testDir = t.testdir({
150+
package: {
151+
'package.json': JSON.stringify({
152+
name: 'my-cool-pkg',
153+
version: '1.0.0',
154+
}, null, 2),
155+
node_modules: {
156+
'bundle-dep': {
157+
'package.json': JSON.stringify({
158+
name: 'bundle-dep',
159+
version: '1.0.0',
160+
}, null, 2),
161+
},
162+
},
163+
},
164+
})
165+
166+
await tar.c({
167+
gzip: true,
168+
file: 'npm-example-v1.tgz',
169+
C: testDir,
170+
}, ['package'])
171+
172+
const tarball = await readFile(`npm-example-v1.tgz`)
173+
174+
const tarballContents = await getContents({
175+
name: 'my-cool-pkg',
176+
version: '1.0.0',
177+
}, tarball)
178+
179+
const integrity = ssri.fromData(tarball, {
180+
algorithms: ['sha1', 'sha512'],
181+
})
182+
183+
// zlib is nondeterministic
184+
t.match(tarballContents.shasum, /^[0-9a-f]{40}$/)
185+
delete tarballContents.shasum
186+
187+
// assert mode differently according to platform
188+
if (process.platform === 'win32') {
189+
tarballContents.files[0].mode = 511
190+
tarballContents.files[1].mode = 511
191+
tarballContents.files[2].mode = 511
192+
tarballContents.files[3].mode = 438
193+
tarballContents.files[4].mode = 438
194+
} else {
195+
tarballContents.files[0].mode = 493
196+
tarballContents.files[1].mode = 493
197+
tarballContents.files[2].mode = 493
198+
tarballContents.files[3].mode = 420
199+
tarballContents.files[4].mode = 420
200+
}
201+
202+
tarballContents.files.forEach((file) => {
203+
delete file.mode
204+
})
205+
206+
t.same(tarballContents, {
207+
208+
name: 'my-cool-pkg',
209+
version: '1.0.0',
210+
size: tarball.length,
211+
unpackedSize: 97,
212+
integrity: ssri.parse(integrity.sha512[0]),
213+
filename: 'my-cool-pkg-1.0.0.tgz',
214+
files: [
215+
{ path: '', size: 0 },
216+
{ path: 'node_modules/', size: 0 },
217+
{ path: 'node_modules/bundle-dep/', size: 0 },
218+
{ path: 'node_modules/bundle-dep/package.json', size: 48 },
219+
{ path: 'package.json', size: 49 },
220+
],
221+
entryCount: 5,
222+
bundled: ['bundle-dep'],
223+
}, 'contents are correct')
224+
t.end()
225+
})

0 commit comments

Comments
 (0)