Skip to content

Commit 6b3f445

Browse files
fix sonar issues
1 parent 9775392 commit 6b3f445

5 files changed

Lines changed: 18 additions & 15 deletions

File tree

models/boardRepository.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function createBoardRepository(config) {
2222
}
2323

2424
async function writeSplitBoard(board) {
25-
await fs.mkdir(safePathInsideRoot(config.boardDir, config.workspaceDir), { recursive: true });
25+
await fs.mkdir(safePathInsideRoot(config.boardDir, config.workspaceDir), { recursive: true }); // NOSONAR: path is constrained to the configured vault root.
2626
const {
2727
lists,
2828
labels,
@@ -46,7 +46,7 @@ function createBoardRepository(config) {
4646
const directory = safePathInsideRoot(path.join(config.boardDir, name), config.boardDir);
4747
let entries = [];
4848
try {
49-
entries = await fs.readdir(directory, { withFileTypes: true });
49+
entries = await fs.readdir(directory, { withFileTypes: true }); // NOSONAR: directory is constrained to the board data root.
5050
} catch (error) {
5151
if (error.code === "ENOENT") return [];
5252
throw error;
@@ -62,7 +62,7 @@ function createBoardRepository(config) {
6262

6363
async function writeJsonCollection(name, items) {
6464
const directory = safePathInsideRoot(path.join(config.boardDir, name), config.boardDir);
65-
await fs.mkdir(directory, { recursive: true });
65+
await fs.mkdir(directory, { recursive: true }); // NOSONAR: directory is constrained to the board data root.
6666
const desiredFiles = new Set();
6767

6868
for (const item of items) {
@@ -76,7 +76,7 @@ function createBoardRepository(config) {
7676

7777
let entries = [];
7878
try {
79-
entries = await fs.readdir(directory, { withFileTypes: true });
79+
entries = await fs.readdir(directory, { withFileTypes: true }); // NOSONAR: directory is constrained to the board data root.
8080
} catch (error) {
8181
if (error.code === "ENOENT") return;
8282
throw error;

services/boardService.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function createBoardService(config) {
2020
async function seedBoard() {
2121
try {
2222
if (await exists(config.boardFilePath, config.workspaceDir)) {
23-
const raw = await fs.readFile(safePathInsideRoot(config.boardFilePath, config.workspaceDir), "utf8");
23+
const raw = await fs.readFile(safePathInsideRoot(config.boardFilePath, config.workspaceDir), "utf8"); // NOSONAR: board file is constrained to the vault root.
2424
return normalizer.normalizeBoard(JSON.parse(raw));
2525
}
2626
} catch {
@@ -29,14 +29,14 @@ function createBoardService(config) {
2929

3030
try {
3131
const sampleExportDir = safePathInsideRoot(config.sampleExportDir, config.workspaceDir);
32-
const entries = await fs.readdir(sampleExportDir, { withFileTypes: true });
32+
const entries = await fs.readdir(sampleExportDir, { withFileTypes: true }); // NOSONAR: sample directory is constrained to the vault root.
3333
const sample = entries
3434
.filter((entry) => entry.isFile() && entry.name.toLowerCase().endsWith(".json"))
3535
.sort((left, right) => left.name.localeCompare(right.name))[0];
3636

3737
if (sample) {
3838
const samplePath = safePathInsideRoot(path.join(sampleExportDir, sample.name), sampleExportDir);
39-
const raw = await fs.readFile(samplePath, "utf8");
39+
const raw = await fs.readFile(samplePath, "utf8"); // NOSONAR: sample file is constrained to the sample export directory.
4040
return normalizer.normalizeBoard(JSON.parse(raw));
4141
}
4242
} catch {

services/gitService.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function createGitService(config) {
1010
async function hasGitRepository(rootPath = config.workspaceDir) {
1111
try {
1212
const gitPath = safePathInsideRoot(path.join(rootPath, ".git"), config.workspaceDir);
13-
const stat = await fs.stat(gitPath);
13+
const stat = await fs.stat(gitPath); // NOSONAR: git path is constrained to the configured vault root.
1414
return stat.isDirectory() || stat.isFile();
1515
} catch {
1616
return false;

utils/fileUtils.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const { safePathInsideRoot } = require("./pathUtils");
66

77
async function exists(filePath, rootPath) {
88
try {
9-
await fs.access(safePathInsideRoot(filePath, rootPath));
9+
await fs.access(safePathInsideRoot(filePath, rootPath)); // NOSONAR: path is constrained to the caller-provided root.
1010
return true;
1111
} catch {
1212
return false;
@@ -15,7 +15,7 @@ async function exists(filePath, rootPath) {
1515

1616
async function readJsonFile(filePath, fallback, rootPath) {
1717
try {
18-
return JSON.parse(await fs.readFile(safePathInsideRoot(filePath, rootPath), "utf8"));
18+
return JSON.parse(await fs.readFile(safePathInsideRoot(filePath, rootPath), "utf8")); // NOSONAR: path is constrained to the caller-provided root.
1919
} catch (error) {
2020
if (error.code === "ENOENT") return fallback;
2121
throw error;
@@ -26,7 +26,7 @@ async function writeJsonIfChanged(filePath, value, rootPath) {
2626
const safePath = safePathInsideRoot(filePath, rootPath);
2727
const next = `${JSON.stringify(value, null, 2)}\n`;
2828
try {
29-
const current = await fs.readFile(safePath, "utf8");
29+
const current = await fs.readFile(safePath, "utf8"); // NOSONAR: safePath is constrained to the caller-provided root.
3030
if (current === next) return;
3131
} catch (error) {
3232
if (error.code !== "ENOENT") throw error;
@@ -39,8 +39,8 @@ async function writeTextAtomically(filePath, text, rootPath) {
3939
const directory = path.dirname(safePath);
4040
const tmpPath = safePathInsideRoot(`${safePath}.${process.pid}.${Date.now()}.tmp`, rootPath);
4141
await fs.mkdir(directory, { recursive: true });
42-
await fs.writeFile(tmpPath, text, "utf8");
43-
await fs.rename(tmpPath, safePath);
42+
await fs.writeFile(tmpPath, text, "utf8"); // NOSONAR: tmpPath is constrained to the caller-provided root.
43+
await fs.rename(tmpPath, safePath); // NOSONAR: both paths are constrained to the caller-provided root.
4444
}
4545

4646
module.exports = {

utils/pathUtils.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ function canonicalWorkspacePath(candidatePath, allowedRoots) {
99
throw new Error("Invalid workspace path.");
1010
}
1111

12-
fsSync.mkdirSync(resolvedPath, { recursive: true });
13-
const canonicalPath = fsSync.realpathSync(resolvedPath);
1412
const allowed = allowedRoots.map(canonicalDirectory);
13+
if (!allowed.some((rootPath) => isPathInside(resolvedPath, rootPath))) {
14+
throw new Error("Workspace path must be inside your home directory, current directory, or temporary directory.");
15+
}
16+
fsSync.mkdirSync(resolvedPath, { recursive: true }); // NOSONAR: resolvedPath is validated against allowed roots above.
17+
const canonicalPath = fsSync.realpathSync(resolvedPath); // NOSONAR: resolvedPath is validated against allowed roots above.
1518
if (!allowed.some((rootPath) => isPathInside(canonicalPath, rootPath))) {
1619
throw new Error("Workspace path must be inside your home directory, current directory, or temporary directory.");
1720
}

0 commit comments

Comments
 (0)