refactor: use type enum in file stats for asar archive (#39889)
This commit is contained in:
parent
18f517d8a6
commit
d75a852743
5 changed files with 31 additions and 40 deletions
|
@ -1,4 +1,5 @@
|
||||||
import { Buffer } from 'buffer';
|
import { Buffer } from 'buffer';
|
||||||
|
import { constants } from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as util from 'util';
|
import * as util from 'util';
|
||||||
import type * as Crypto from 'crypto';
|
import type * as Crypto from 'crypto';
|
||||||
|
@ -75,19 +76,23 @@ const gid = process.getgid?.() ?? 0;
|
||||||
|
|
||||||
const fakeTime = new Date();
|
const fakeTime = new Date();
|
||||||
|
|
||||||
const asarStatsToFsStats = function (stats: NodeJS.AsarFileStat) {
|
enum AsarFileType {
|
||||||
const { Stats, constants } = require('fs');
|
kFile = (constants as any).UV_DIRENT_FILE,
|
||||||
|
kDirectory = (constants as any).UV_DIRENT_DIR,
|
||||||
let mode = constants.S_IROTH ^ constants.S_IRGRP ^ constants.S_IRUSR ^ constants.S_IWUSR;
|
kLink = (constants as any).UV_DIRENT_LINK,
|
||||||
|
|
||||||
if (stats.isFile) {
|
|
||||||
mode ^= constants.S_IFREG;
|
|
||||||
} else if (stats.isDirectory) {
|
|
||||||
mode ^= constants.S_IFDIR;
|
|
||||||
} else if (stats.isLink) {
|
|
||||||
mode ^= constants.S_IFLNK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fileTypeToMode = new Map<AsarFileType, number>([
|
||||||
|
[AsarFileType.kFile, constants.S_IFREG],
|
||||||
|
[AsarFileType.kDirectory, constants.S_IFDIR],
|
||||||
|
[AsarFileType.kLink, constants.S_IFLNK]
|
||||||
|
]);
|
||||||
|
|
||||||
|
const asarStatsToFsStats = function (stats: NodeJS.AsarFileStat) {
|
||||||
|
const { Stats } = require('fs');
|
||||||
|
|
||||||
|
const mode = constants.S_IROTH | constants.S_IRGRP | constants.S_IRUSR | constants.S_IWUSR | fileTypeToMode.get(stats.type)!;
|
||||||
|
|
||||||
return new Stats(
|
return new Stats(
|
||||||
1, // dev
|
1, // dev
|
||||||
mode, // mode
|
mode, // mode
|
||||||
|
@ -249,7 +254,6 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||||
const logASARAccess = (asarPath: string, filePath: string, offset: number) => {
|
const logASARAccess = (asarPath: string, filePath: string, offset: number) => {
|
||||||
if (!process.env.ELECTRON_LOG_ASAR_READS) return;
|
if (!process.env.ELECTRON_LOG_ASAR_READS) return;
|
||||||
if (!logFDs.has(asarPath)) {
|
if (!logFDs.has(asarPath)) {
|
||||||
const path = require('path');
|
|
||||||
const logFilename = `${path.basename(asarPath, '.asar')}-access-log.txt`;
|
const logFilename = `${path.basename(asarPath, '.asar')}-access-log.txt`;
|
||||||
const logPath = path.join(require('os').tmpdir(), logFilename);
|
const logPath = path.join(require('os').tmpdir(), logFilename);
|
||||||
logFDs.set(asarPath, fs.openSync(logPath, 'a'));
|
logFDs.set(asarPath, fs.openSync(logPath, 'a'));
|
||||||
|
@ -676,13 +680,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||||
nextTick(callback!, [error]);
|
nextTick(callback!, [error]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (stats.isFile) {
|
dirents.push(new fs.Dirent(file, stats.type));
|
||||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
|
|
||||||
} else if (stats.isDirectory) {
|
|
||||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_DIR));
|
|
||||||
} else if (stats.isLink) {
|
|
||||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_LINK));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
nextTick(callback!, [null, dirents]);
|
nextTick(callback!, [null, dirents]);
|
||||||
return;
|
return;
|
||||||
|
@ -719,13 +717,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||||
if (!stats) {
|
if (!stats) {
|
||||||
throw createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
|
throw createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
|
||||||
}
|
}
|
||||||
if (stats.isFile) {
|
dirents.push(new fs.Dirent(file, stats.type));
|
||||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
|
|
||||||
} else if (stats.isDirectory) {
|
|
||||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_DIR));
|
|
||||||
} else if (stats.isLink) {
|
|
||||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_LINK));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return dirents;
|
return dirents;
|
||||||
}
|
}
|
||||||
|
@ -776,7 +768,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||||
const stats = archive.stat(filePath);
|
const stats = archive.stat(filePath);
|
||||||
if (!stats) return -34;
|
if (!stats) return -34;
|
||||||
|
|
||||||
return (stats.isDirectory) ? 1 : 0;
|
return (stats.type === AsarFileType.kDirectory) ? 1 : 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calling mkdir for directory inside asar archive should throw ENOTDIR
|
// Calling mkdir for directory inside asar archive should throw ENOTDIR
|
||||||
|
|
|
@ -121,9 +121,7 @@ class Archive : public node::ObjectWrap {
|
||||||
gin_helper::Dictionary dict(isolate, v8::Object::New(isolate));
|
gin_helper::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||||
dict.Set("size", stats.size);
|
dict.Set("size", stats.size);
|
||||||
dict.Set("offset", stats.offset);
|
dict.Set("offset", stats.offset);
|
||||||
dict.Set("isFile", stats.is_file);
|
dict.Set("type", static_cast<int>(stats.type));
|
||||||
dict.Set("isDirectory", stats.is_directory);
|
|
||||||
dict.Set("isLink", stats.is_link);
|
|
||||||
args.GetReturnValue().Set(dict.GetHandle());
|
args.GetReturnValue().Set(dict.GetHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -311,14 +311,12 @@ bool Archive::Stat(const base::FilePath& path, Stats* stats) const {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (node->Find("link")) {
|
if (node->Find("link")) {
|
||||||
stats->is_file = false;
|
stats->type = FileType::kLink;
|
||||||
stats->is_link = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->Find("files")) {
|
if (node->Find("files")) {
|
||||||
stats->is_file = false;
|
stats->type = FileType::kDirectory;
|
||||||
stats->is_directory = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
#include "base/files/file.h"
|
#include "base/files/file.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/synchronization/lock.h"
|
#include "base/synchronization/lock.h"
|
||||||
|
@ -49,11 +51,14 @@ class Archive {
|
||||||
absl::optional<IntegrityPayload> integrity;
|
absl::optional<IntegrityPayload> integrity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class FileType {
|
||||||
|
kFile = UV_DIRENT_FILE,
|
||||||
|
kDirectory = UV_DIRENT_DIR,
|
||||||
|
kLink = UV_DIRENT_LINK,
|
||||||
|
};
|
||||||
|
|
||||||
struct Stats : public FileInfo {
|
struct Stats : public FileInfo {
|
||||||
Stats() : is_file(true), is_directory(false), is_link(false) {}
|
FileType type = FileType::kFile;
|
||||||
bool is_file;
|
|
||||||
bool is_directory;
|
|
||||||
bool is_link;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit Archive(const base::FilePath& path);
|
explicit Archive(const base::FilePath& path);
|
||||||
|
|
4
typings/internal-ambient.d.ts
vendored
4
typings/internal-ambient.d.ts
vendored
|
@ -72,9 +72,7 @@ declare namespace NodeJS {
|
||||||
type AsarFileStat = {
|
type AsarFileStat = {
|
||||||
size: number;
|
size: number;
|
||||||
offset: number;
|
offset: number;
|
||||||
isFile: boolean;
|
type: number;
|
||||||
isDirectory: boolean;
|
|
||||||
isLink: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AsarArchive {
|
interface AsarArchive {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue