From d75a852743283026d71d9f743032eaea84691a11 Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Mon, 25 Sep 2023 13:17:24 +0200 Subject: [PATCH] refactor: use type enum in file stats for asar archive (#39889) --- lib/asar/fs-wrapper.ts | 44 +++++++++++---------------- shell/common/api/electron_api_asar.cc | 4 +-- shell/common/asar/archive.cc | 6 ++-- shell/common/asar/archive.h | 13 +++++--- typings/internal-ambient.d.ts | 4 +-- 5 files changed, 31 insertions(+), 40 deletions(-) diff --git a/lib/asar/fs-wrapper.ts b/lib/asar/fs-wrapper.ts index 0d7b8e8cecbe..e7e92d28f9f1 100644 --- a/lib/asar/fs-wrapper.ts +++ b/lib/asar/fs-wrapper.ts @@ -1,4 +1,5 @@ import { Buffer } from 'buffer'; +import { constants } from 'fs'; import * as path from 'path'; import * as util from 'util'; import type * as Crypto from 'crypto'; @@ -75,18 +76,22 @@ const gid = process.getgid?.() ?? 0; const fakeTime = new Date(); +enum AsarFileType { + kFile = (constants as any).UV_DIRENT_FILE, + kDirectory = (constants as any).UV_DIRENT_DIR, + kLink = (constants as any).UV_DIRENT_LINK, +} + +const fileTypeToMode = new Map([ + [AsarFileType.kFile, constants.S_IFREG], + [AsarFileType.kDirectory, constants.S_IFDIR], + [AsarFileType.kLink, constants.S_IFLNK] +]); + const asarStatsToFsStats = function (stats: NodeJS.AsarFileStat) { - const { Stats, constants } = require('fs'); + const { Stats } = require('fs'); - let mode = constants.S_IROTH ^ constants.S_IRGRP ^ constants.S_IRUSR ^ constants.S_IWUSR; - - if (stats.isFile) { - mode ^= constants.S_IFREG; - } else if (stats.isDirectory) { - mode ^= constants.S_IFDIR; - } else if (stats.isLink) { - mode ^= constants.S_IFLNK; - } + const mode = constants.S_IROTH | constants.S_IRGRP | constants.S_IRUSR | constants.S_IWUSR | fileTypeToMode.get(stats.type)!; return new Stats( 1, // dev @@ -249,7 +254,6 @@ export const wrapFsWithAsar = (fs: Record) => { const logASARAccess = (asarPath: string, filePath: string, offset: number) => { if (!process.env.ELECTRON_LOG_ASAR_READS) return; if (!logFDs.has(asarPath)) { - const path = require('path'); const logFilename = `${path.basename(asarPath, '.asar')}-access-log.txt`; const logPath = path.join(require('os').tmpdir(), logFilename); logFDs.set(asarPath, fs.openSync(logPath, 'a')); @@ -676,13 +680,7 @@ export const wrapFsWithAsar = (fs: Record) => { nextTick(callback!, [error]); return; } - if (stats.isFile) { - 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)); - } + dirents.push(new fs.Dirent(file, stats.type)); } nextTick(callback!, [null, dirents]); return; @@ -719,13 +717,7 @@ export const wrapFsWithAsar = (fs: Record) => { if (!stats) { throw createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath }); } - if (stats.isFile) { - 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)); - } + dirents.push(new fs.Dirent(file, stats.type)); } return dirents; } @@ -776,7 +768,7 @@ export const wrapFsWithAsar = (fs: Record) => { const stats = archive.stat(filePath); 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 diff --git a/shell/common/api/electron_api_asar.cc b/shell/common/api/electron_api_asar.cc index f0adf8b53a2d..3a5cad2451a6 100644 --- a/shell/common/api/electron_api_asar.cc +++ b/shell/common/api/electron_api_asar.cc @@ -121,9 +121,7 @@ class Archive : public node::ObjectWrap { gin_helper::Dictionary dict(isolate, v8::Object::New(isolate)); dict.Set("size", stats.size); dict.Set("offset", stats.offset); - dict.Set("isFile", stats.is_file); - dict.Set("isDirectory", stats.is_directory); - dict.Set("isLink", stats.is_link); + dict.Set("type", static_cast(stats.type)); args.GetReturnValue().Set(dict.GetHandle()); } diff --git a/shell/common/asar/archive.cc b/shell/common/asar/archive.cc index b56701864254..905fafe74ec3 100644 --- a/shell/common/asar/archive.cc +++ b/shell/common/asar/archive.cc @@ -311,14 +311,12 @@ bool Archive::Stat(const base::FilePath& path, Stats* stats) const { return false; if (node->Find("link")) { - stats->is_file = false; - stats->is_link = true; + stats->type = FileType::kLink; return true; } if (node->Find("files")) { - stats->is_file = false; - stats->is_directory = true; + stats->type = FileType::kDirectory; return true; } diff --git a/shell/common/asar/archive.h b/shell/common/asar/archive.h index 0a8ff89314b9..b11f2ac212f7 100644 --- a/shell/common/asar/archive.h +++ b/shell/common/asar/archive.h @@ -10,6 +10,8 @@ #include #include +#include + #include "base/files/file.h" #include "base/files/file_path.h" #include "base/synchronization/lock.h" @@ -49,11 +51,14 @@ class Archive { absl::optional integrity; }; + enum class FileType { + kFile = UV_DIRENT_FILE, + kDirectory = UV_DIRENT_DIR, + kLink = UV_DIRENT_LINK, + }; + struct Stats : public FileInfo { - Stats() : is_file(true), is_directory(false), is_link(false) {} - bool is_file; - bool is_directory; - bool is_link; + FileType type = FileType::kFile; }; explicit Archive(const base::FilePath& path); diff --git a/typings/internal-ambient.d.ts b/typings/internal-ambient.d.ts index 6f6eaafb62b0..9bcf3c3d5769 100644 --- a/typings/internal-ambient.d.ts +++ b/typings/internal-ambient.d.ts @@ -72,9 +72,7 @@ declare namespace NodeJS { type AsarFileStat = { size: number; offset: number; - isFile: boolean; - isDirectory: boolean; - isLink: boolean; + type: number; } interface AsarArchive {