autosnippet 3.1.3 → 3.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/mcp-server.js
CHANGED
|
File without changes
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import fs from 'node:fs/promises';
|
|
10
10
|
import path from 'node:path';
|
|
11
11
|
import Logger from '../../../../../infrastructure/logging/Logger.js';
|
|
12
|
+
import pathGuard from '../../../../../shared/PathGuard.js';
|
|
12
13
|
|
|
13
14
|
const logger = Logger.getInstance();
|
|
14
15
|
|
|
@@ -79,8 +80,12 @@ export async function loadCheckpoints(projectRoot) {
|
|
|
79
80
|
export async function clearCheckpoints(projectRoot) {
|
|
80
81
|
try {
|
|
81
82
|
const checkpointDir = path.join(projectRoot, '.autosnippet', 'bootstrap-checkpoint');
|
|
83
|
+
pathGuard.assertSafe(checkpointDir);
|
|
82
84
|
await fs.rm(checkpointDir, { recursive: true, force: true });
|
|
83
|
-
} catch {
|
|
84
|
-
|
|
85
|
+
} catch (err) {
|
|
86
|
+
if (err?.name === 'PathGuardError') {
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
89
|
+
/* ignore other errors */
|
|
85
90
|
}
|
|
86
91
|
}
|
|
@@ -309,6 +309,7 @@ export class KnowledgeFileWriter {
|
|
|
309
309
|
if (entry.sourceFile) {
|
|
310
310
|
const fullPath = path.join(this.projectRoot, entry.sourceFile);
|
|
311
311
|
if (fs.existsSync(fullPath)) {
|
|
312
|
+
pathGuard.assertSafe(fullPath);
|
|
312
313
|
fs.unlinkSync(fullPath);
|
|
313
314
|
this.logger.info('Knowledge entry file removed', {
|
|
314
315
|
entryId: entry.id,
|
|
@@ -328,6 +329,7 @@ export class KnowledgeFileWriter {
|
|
|
328
329
|
for (const dir of searchDirs) {
|
|
329
330
|
const fp = path.join(dir, filename);
|
|
330
331
|
if (fs.existsSync(fp)) {
|
|
332
|
+
pathGuard.assertSafe(fp);
|
|
331
333
|
fs.unlinkSync(fp);
|
|
332
334
|
this.logger.info('Knowledge entry file removed', { entryId: entry.id, path: fp });
|
|
333
335
|
return true;
|
|
@@ -358,6 +360,7 @@ export class KnowledgeFileWriter {
|
|
|
358
360
|
|
|
359
361
|
// 删除旧文件
|
|
360
362
|
if (oldPath && fs.existsSync(oldPath)) {
|
|
363
|
+
pathGuard.assertSafe(oldPath);
|
|
361
364
|
fs.unlinkSync(oldPath);
|
|
362
365
|
this.logger.info('Removed old knowledge entry file on lifecycle change', {
|
|
363
366
|
entryId: entry.id,
|
|
@@ -392,6 +395,7 @@ export class KnowledgeFileWriter {
|
|
|
392
395
|
}
|
|
393
396
|
const oldPath = path.join(this.projectRoot, entry.sourceFile);
|
|
394
397
|
if (oldPath !== newPath && fs.existsSync(oldPath)) {
|
|
398
|
+
pathGuard.assertSafe(oldPath);
|
|
395
399
|
fs.unlinkSync(oldPath);
|
|
396
400
|
this.logger.info('Cleaned up old knowledge entry file', {
|
|
397
401
|
entryId: entry.id,
|
|
@@ -675,6 +679,7 @@ function _walkAndRemoveById(dir, id) {
|
|
|
675
679
|
} else if (entry.name.endsWith('.md') && !entry.name.startsWith('_')) {
|
|
676
680
|
const head = fs.readFileSync(full, 'utf8').slice(0, 500);
|
|
677
681
|
if (head.includes(`id: ${id}`)) {
|
|
682
|
+
pathGuard.assertSafe(full);
|
|
678
683
|
fs.unlinkSync(full);
|
|
679
684
|
return true;
|
|
680
685
|
}
|
|
@@ -332,6 +332,10 @@ export function dedup(files, wikiDir, emit) {
|
|
|
332
332
|
// 完全相同 hash → 移除后来的
|
|
333
333
|
if (existing.hash === file.hash) {
|
|
334
334
|
const fullPath = path.join(wikiDir, file.path);
|
|
335
|
+
if (!fullPath.startsWith(path.resolve(wikiDir) + path.sep)) {
|
|
336
|
+
logger.warn(`[WikiGenerator] Dedup: path escape blocked — ${file.path}`);
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
335
339
|
try {
|
|
336
340
|
fs.unlinkSync(fullPath);
|
|
337
341
|
} catch {
|
|
@@ -361,6 +365,10 @@ export function dedup(files, wikiDir, emit) {
|
|
|
361
365
|
if (isCurrentSynced && !isFirstSynced) {
|
|
362
366
|
// 当前是 synced,first 是 codegen → 删除 synced
|
|
363
367
|
const fullPath = path.join(wikiDir, file.path);
|
|
368
|
+
if (!fullPath.startsWith(path.resolve(wikiDir) + path.sep)) {
|
|
369
|
+
logger.warn(`[WikiGenerator] Dedup: path escape blocked — ${file.path}`);
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
364
372
|
try {
|
|
365
373
|
fs.unlinkSync(fullPath);
|
|
366
374
|
} catch {
|