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,18 +76,22 @@ const gid = process.getgid?.() ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const fakeTime = new Date();
 | 
					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, number>([
 | 
				
			||||||
 | 
					  [AsarFileType.kFile, constants.S_IFREG],
 | 
				
			||||||
 | 
					  [AsarFileType.kDirectory, constants.S_IFDIR],
 | 
				
			||||||
 | 
					  [AsarFileType.kLink, constants.S_IFLNK]
 | 
				
			||||||
 | 
					]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const asarStatsToFsStats = function (stats: NodeJS.AsarFileStat) {
 | 
					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;
 | 
					  const mode = constants.S_IROTH | constants.S_IRGRP | constants.S_IRUSR | constants.S_IWUSR | fileTypeToMode.get(stats.type)!;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (stats.isFile) {
 | 
					 | 
				
			||||||
    mode ^= constants.S_IFREG;
 | 
					 | 
				
			||||||
  } else if (stats.isDirectory) {
 | 
					 | 
				
			||||||
    mode ^= constants.S_IFDIR;
 | 
					 | 
				
			||||||
  } else if (stats.isLink) {
 | 
					 | 
				
			||||||
    mode ^= constants.S_IFLNK;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return new Stats(
 | 
					  return new Stats(
 | 
				
			||||||
    1, // dev
 | 
					    1, // dev
 | 
				
			||||||
| 
						 | 
					@ -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