Skip to content

Commit

Permalink
fix(utils/tar): index access while match is null (#7555) (#7556)
Browse files Browse the repository at this point in the history
Details explained in issue #7555

Closes #7555
  • Loading branch information
NormanPerrin authored May 29, 2024
1 parent 2d1d8d0 commit 8f94ae8
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 3 deletions.
4 changes: 2 additions & 2 deletions lib/utils/tar.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const getContents = async (manifest, tarball) => {
totalEntries++
totalEntrySize += entry.size
const p = entry.path
if (p.startsWith('package/node_modules/')) {
if (p.startsWith('package/node_modules/') && p !== 'package/node_modules/') {
const name = p.match(/^package\/node_modules\/((?:@[^/]+\/)?[^/]+)/)[1]
bundled.add(name)
}
Expand All @@ -72,7 +72,7 @@ const getContents = async (manifest, tarball) => {
})
stream.end(tarball)

const integrity = await ssri.fromData(tarball, {
const integrity = ssri.fromData(tarball, {
algorithms: ['sha1', 'sha512'],
})

Expand Down
83 changes: 82 additions & 1 deletion test/lib/utils/tar.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const t = require('tap')
const tar = require('tar')
const pack = require('libnpmpack')
const ssri = require('ssri')
const { readFile } = require('fs/promises')
const tmock = require('../../fixtures/tmock')
const { cleanZlib } = require('../../fixtures/clean-snapshot')

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

t.test('should getContents of a tarball', async (t) => {
t.test('should getContents of a tarball with only a package.json', async (t) => {
const testDir = t.testdir({
'package.json': JSON.stringify({
name: 'my-cool-pkg',
Expand Down Expand Up @@ -142,3 +144,82 @@ t.test('should getContents of a tarball', async (t) => {
}, 'contents are correct')
t.end()
})

t.test('should getContents of a tarball with a node_modules directory included', async (t) => {
const testDir = t.testdir({
package: {
'package.json': JSON.stringify({
name: 'my-cool-pkg',
version: '1.0.0',
}, null, 2),
node_modules: {
'bundle-dep': {
'package.json': JSON.stringify({
name: 'bundle-dep',
version: '1.0.0',
}, null, 2),
},
},
},
})

await tar.c({
gzip: true,
file: 'npm-example-v1.tgz',
C: testDir,
}, ['package'])

const tarball = await readFile(`npm-example-v1.tgz`)

const tarballContents = await getContents({
name: 'my-cool-pkg',
version: '1.0.0',
}, tarball)

const integrity = ssri.fromData(tarball, {
algorithms: ['sha1', 'sha512'],
})

// zlib is nondeterministic
t.match(tarballContents.shasum, /^[0-9a-f]{40}$/)
delete tarballContents.shasum

// assert mode differently according to platform
if (process.platform === 'win32') {
tarballContents.files[0].mode = 511
tarballContents.files[1].mode = 511
tarballContents.files[2].mode = 511
tarballContents.files[3].mode = 438
tarballContents.files[4].mode = 438
} else {
tarballContents.files[0].mode = 493
tarballContents.files[1].mode = 493
tarballContents.files[2].mode = 493
tarballContents.files[3].mode = 420
tarballContents.files[4].mode = 420
}

tarballContents.files.forEach((file) => {
delete file.mode
})

t.same(tarballContents, {
id: 'my-cool-pkg@1.0.0',
name: 'my-cool-pkg',
version: '1.0.0',
size: tarball.length,
unpackedSize: 97,
integrity: ssri.parse(integrity.sha512[0]),
filename: 'my-cool-pkg-1.0.0.tgz',
files: [
{ path: '', size: 0 },
{ path: 'node_modules/', size: 0 },
{ path: 'node_modules/bundle-dep/', size: 0 },
{ path: 'node_modules/bundle-dep/package.json', size: 48 },
{ path: 'package.json', size: 49 },
],
entryCount: 5,
bundled: ['bundle-dep'],
}, 'contents are correct')
t.end()
})

0 comments on commit 8f94ae8

Please # to comment.