diff --git a/tools/packaging/release-snap-assets.test.mjs b/tools/packaging/release-snap-assets.test.mjs index c2e4315a8..97a9a5e53 100644 --- a/tools/packaging/release-snap-assets.test.mjs +++ b/tools/packaging/release-snap-assets.test.mjs @@ -904,6 +904,45 @@ test('hashes the final source archive bytes and reads the exact packaged Snap bi assert.equal(tarResult.error, undefined); assert.equal(tarResult.status, 0, tarResult.stderr); + let observedTarFilesFromFile = false; + const runCommand = (command, args, options = {}) => { + if (command === 'tar' && args.includes('-T')) { + const filesFromPath = args[args.indexOf('-T') + 1]; + assert.equal(path.isAbsolute(filesFromPath), true); + assert.equal(fs.lstatSync(filesFromPath).isFile(), true); + assert.equal( + fs.lstatSync(filesFromPath).mode & 0o077, + 0, + 'tar files-from input must not be group/world accessible' + ); + assert.match( + fs.readFileSync(filesFromPath, 'utf8'), + /git\/libplacebo\/README\.md/ + ); + observedTarFilesFromFile = true; + } + const result = childProcess.spawnSync(command, args, { + encoding: + options.encoding === undefined ? 'utf8' : options.encoding, + input: options.input, + killSignal: 'SIGKILL', + maxBuffer: options.maxBuffer, + stdio: 'pipe', + timeout: options.timeout, + windowsHide: true, + }); + if (result.error) { + throw result.error; + } + if (result.status !== 0) { + throw new Error( + `${command} exited with status ${String(result.status)}: ${ + result.stderr ?? '' + }` + ); + } + return result.stdout; + }; const sourceArchive = sourceArchiveContract.createLinuxSourceArchiveBinding( { archivePath: sourceArchivePath, @@ -911,15 +950,20 @@ test('hashes the final source archive bytes and reads the exact packaged Snap bi } ); assert.throws( - () => sourceBindingHelper.inspectSourceArchive(sourceArchivePath), + () => + sourceBindingHelper.inspectSourceArchive(sourceArchivePath, { + runCommand, + }), /snapshot digest mismatch/i ); const sourceInspection = sourceBindingHelper.inspectSourceArchive( sourceArchivePath, { expectedSourceSnapshotSha256: fixture.expectedSourceSnapshotSha256, + runCommand, } ); + assert.equal(observedTarFilesFromFile, true); assert.equal(sourceInspection.archiveSha256, sourceArchive.sha256); assert.deepEqual(sourceInspection.archiveFiles, sourceIndex.archives); diff --git a/tools/packaging/release-snap-source-binding.cjs b/tools/packaging/release-snap-source-binding.cjs index 2624b2fde..9b642e610 100644 --- a/tools/packaging/release-snap-source-binding.cjs +++ b/tools/packaging/release-snap-source-binding.cjs @@ -546,6 +546,19 @@ function inspectLibplaceboSourceSnapshot( path.join(os.tmpdir(), 'iptvnator-libplacebo-source-verifier-') ); try { + const memberListPath = path.join( + temporaryRoot, + 'libplacebo-members.txt' + ); + fs.writeFileSync( + memberListPath, + `${sourceMembers.map(({ rawName }) => rawName).join('\n')}\n`, + { + encoding: 'utf8', + flag: 'wx', + mode: 0o600, + } + ); runCommand( 'tar', [ @@ -558,14 +571,10 @@ function inspectLibplaceboSourceSnapshot( '--no-same-owner', '--no-same-permissions', '-T', - '/dev/stdin', + memberListPath, ], { encoding: 'utf8', - input: Buffer.from( - `${sourceMembers.map(({ rawName }) => rawName).join('\n')}\n`, - 'utf8' - ), maxBuffer: COMMAND_OUTPUT_MAX_BUFFER_BYTES, } );