Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add file hashes to asar header #221

Merged
merged 14 commits into from
Sep 9, 2021
Merged
4 changes: 4 additions & 0 deletions lib/asar.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ module.exports.statFile = function (archive, filename, followLinks) {
return filesystem.getFile(filename, followLinks)
}

module.exports.getRawHeader = function (archive) {
return disk.readArchiveHeaderSync(archive)
}

module.exports.listPackage = function (archive, options) {
return disk.readFilesystemSync(archive).listFiles(options)
}
Expand Down
2 changes: 1 addition & 1 deletion lib/disk.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ module.exports.readArchiveHeaderSync = function (archive) {

const headerPickle = pickle.createFromBuffer(headerBuf)
const header = headerPickle.createIterator().readString()
return { header: JSON.parse(header), headerSize: size }
return { headerString: header, header: JSON.parse(header), headerSize: size }
}

module.exports.readFilesystemSync = function (archive) {
Expand Down
3 changes: 3 additions & 0 deletions lib/filesystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const os = require('os')
const path = require('path')
const { promisify } = require('util')
const stream = require('stream')
const hashFile = require('./hash')

const UINT32_MAX = 2 ** 32 - 1

Expand Down Expand Up @@ -57,6 +58,7 @@ class Filesystem {
if (shouldUnpack || dirNode.unpacked) {
node.size = file.stat.size
node.unpacked = true
node.hashes = await hashFile(p)
return Promise.resolve()
}

Expand Down Expand Up @@ -86,6 +88,7 @@ class Filesystem {

node.size = size
node.offset = this.offset.toString()
node.hashes = await hashFile(p)
if (process.platform !== 'win32' && (file.stat.mode & 0o100)) {
node.executable = true
}
Expand Down
28 changes: 28 additions & 0 deletions lib/hash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const crypto = require('crypto')
const fs = require('fs')
const stream = require('stream')
const { promisify } = require('util')

const ALGORITHMS = ['SHA256']

const pipeline = promisify(stream.pipeline)

async function hashFile (path) {
const hashes = {}

await Promise.all(ALGORITHMS.map(async (algo) => {
const read = fs.createReadStream(path)
const hash = crypto.createHash(algo)
hash.setEncoding('base64')
await pipeline(
read,
hash
)

hashes[algo] = hash.read()
}))

return hashes
}

module.exports = hashFile
8 changes: 8 additions & 0 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ export type InputMetadata = {
}
};

export type ArchiveHeader = {
// The JSON parsed header string
header: any;
MarshallOfSound marked this conversation as resolved.
Show resolved Hide resolved
headerString: string;
headerSize: number;
}

export function createPackage(src: string, dest: string): Promise<void>;
export function createPackageWithOptions(
src: string,
Expand All @@ -59,6 +66,7 @@ export function createPackageFromFiles(
): Promise<void>;

export function statFile(archive: string, filename: string, followLinks?: boolean): Metadata;
export function getRawHeader(archive: string): ArchiveHeader;
export function listPackage(archive: string, options?: ListOptions): string[];
export function extractFile(archive: string, filename: string): Buffer;
export function extractAll(archive: string, dest: string): void;
Expand Down
Binary file modified test/expected/packthis-all-unpacked.asar
Binary file not shown.
Binary file modified test/expected/packthis-transformed.asar
Binary file not shown.
Binary file modified test/expected/packthis-unicode-path.asar
Binary file not shown.
Binary file modified test/expected/packthis-unpack-dir-glob.asar
Binary file not shown.
Binary file modified test/expected/packthis-unpack-dir-globstar.asar
Binary file not shown.
Binary file modified test/expected/packthis-unpack-dir.asar
Binary file not shown.
Binary file modified test/expected/packthis-unpack.asar
Binary file not shown.
Binary file modified test/expected/packthis-without-hidden.asar
Binary file not shown.
Binary file modified test/expected/packthis.asar
Binary file not shown.