Clean up code layering suppressions (fix #272777) (#272834)

* Clean up code layering suppressions (fix #272777)

* Update test/unit/electron/index.js

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Benjamin Pasero
2025-10-23 09:28:38 +02:00
committed by GitHub
parent 1395059974
commit 898436fbe6
8 changed files with 106 additions and 16 deletions
+57 -1
View File
@@ -13,7 +13,7 @@ process.env.MOCHA_COLORS = '1';
const { app, BrowserWindow, ipcMain, crashReporter, session } = require('electron');
const product = require('../../../product.json');
const { tmpdir } = require('os');
const { existsSync, mkdirSync } = require('fs');
const { existsSync, mkdirSync, promises } = require('fs');
const path = require('path');
const mocha = require('mocha');
const events = require('events');
@@ -252,6 +252,62 @@ app.on('ready', () => {
// No-op since invoke the IPC as part of IIFE in the preload.
ipcMain.handle('vscode:fetchShellEnv', event => { });
/**
* Validates that a file path is within the project root for security purposes.
* @param {string} filePath - The file path to validate
* @throws {Error} If the path is outside the project root
*/
function validatePathWithinProject(filePath) {
const projectRoot = path.join(__dirname, '../../..');
const resolvedPath = path.resolve(filePath);
const normalizedRoot = path.resolve(projectRoot);
// On Windows, paths are case-insensitive
const isWindows = process.platform === 'win32';
const rel = path.relative(
isWindows ? normalizedRoot.toLowerCase() : normalizedRoot,
isWindows ? resolvedPath.toLowerCase() : resolvedPath
);
if (rel.startsWith('..') || path.isAbsolute(rel)) {
const error = new Error(`Access denied: Path '${filePath}' is outside the project root`);
console.error(error.message);
throw error;
}
}
// Handle file reading for tests
ipcMain.handle('vscode:readFile', async (event, filePath) => {
validatePathWithinProject(filePath);
try {
return await promises.readFile(path.resolve(filePath));
} catch (error) {
console.error(`Error reading file ${filePath}:`, error);
throw error;
}
});
// Handle file stat for tests
ipcMain.handle('vscode:statFile', async (event, filePath) => {
validatePathWithinProject(filePath);
try {
const stats = await promises.stat(path.resolve(filePath));
return {
isFile: stats.isFile(),
isDirectory: stats.isDirectory(),
isSymbolicLink: stats.isSymbolicLink(),
ctimeMs: stats.ctimeMs,
mtimeMs: stats.mtimeMs,
size: stats.size,
isReadonly: (stats.mode & 0o200) === 0 // Check if owner write bit is not set
};
} catch (error) {
console.error(`Error stating file ${filePath}:`, error);
throw error;
}
});
const win = new BrowserWindow({
height: 600,
width: 800,