review.test-mapfile
Test and validate #@mapfile macros with security checks to ensure proper configuration and prevent unauthorized tags in Re:VIEW manuscripts.
Instructions
Test #@mapfile macro with security validation (developer tool)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | Yes | ||
| file | Yes |
Implementation Reference
- src/index.ts:581-629 (handler)Primary handler case for the review.test-mapfile tool in the CallToolRequestSchema switch statement. Performs security validations and delegates to hybridCommands.testMapfile.case "review.test-mapfile": { const securityConfig = await loadSecurityConfig(args.cwd as string); const pathValidation = validateMapfilePath(args.file as string, securityConfig); if (!pathValidation.valid) { return { content: [ { type: "text", text: JSON.stringify({ success: false, error: `Security validation failed: ${pathValidation.reason}` }) } ] }; } const sizeValidation = await validateMapfileSize( args.file as string, args.cwd as string, securityConfig ); if (!sizeValidation.valid) { return { content: [ { type: "text", text: JSON.stringify({ success: false, error: `File size validation failed: ${sizeValidation.reason}` }) } ] }; } const result = await hybridCommands.testMapfile({ file: args.file as string, cwd: args.cwd as string }); return { content: [ { type: "text", text: JSON.stringify(result) } ] }; }
- src/index.ts:353-364 (schema)Tool schema definition, including name, description, and input schema. Part of the tools array returned by ListToolsRequestHandler.{ name: "review.test-mapfile", description: "Test #@mapfile macro with security validation (developer tool)", inputSchema: { type: "object", properties: { cwd: { type: "string" }, file: { type: "string" } }, required: ["cwd", "file"] } },
- src/commands/hybrid-pipeline.ts:132-173 (handler)Core implementation of the mapfile test: creates a temporary Re:VIEW file using the #@mapfile macro, preprocesses it, and returns the processed content.export async function testMapfileCommand(options: TestMapfileOptions) { const { file, cwd } = options; const testFile = path.join(cwd, "test-mapfile.re"); const testContent = `//list[test]{ #@mapfile(${file}) #@end //} `; try { await fs.writeFile(testFile, testContent, "utf-8"); const result = await preprocessCommand({ pattern: "test-mapfile.re", output: ".out", stats: true, cwd }); await fs.unlink(testFile).catch(() => {}); if (result.success) { const outputFile = path.join(cwd, ".out", "test-mapfile.re"); const processedContent = await fs.readFile(outputFile, "utf-8").catch(() => ""); return { success: true, processedContent, stats: result.stats }; } return result; } catch (error: any) { await fs.unlink(testFile).catch(() => {}); return { success: false, error: error.message }; } }
- src/config/security.ts:147-180 (helper)Security helper function validateMapfilePath used in the tool handler to check mapfile path against security policy.export function validateMapfilePath( filepath: string, config: SecurityConfig ): { valid: boolean; reason?: string } { if (config.blockAbsolutePaths && path.isAbsolute(filepath)) { return { valid: false, reason: "Absolute paths are not allowed" }; } if (config.blockTraversal && (filepath.includes("../") || filepath.includes("..\\"))) { return { valid: false, reason: "Path traversal is not allowed" }; } const ext = path.extname(filepath).toLowerCase(); if (config.allowedExtensions.length > 0 && !config.allowedExtensions.includes(ext)) { return { valid: false, reason: `File extension '${ext}' is not allowed. Allowed: ${config.allowedExtensions.join(", ")}` }; } const normalizedPath = filepath.replace(/\\/g, "/"); const isInAllowedPath = config.allowedPaths.length === 0 || config.allowedPaths.some(allowed => normalizedPath.startsWith(allowed)); if (!isInAllowedPath) { return { valid: false, reason: `Path must be within allowed directories: ${config.allowedPaths.join(", ")}` }; } return { valid: true }; }
- src/config/security.ts:182-208 (helper)Security helper function validateMapfileSize used in the tool handler to check mapfile size against security policy.export async function validateMapfileSize( filepath: string, cwd: string, config: SecurityConfig ): Promise<{ valid: boolean; reason?: string; size?: number }> { const fullPath = path.join(cwd, filepath); try { const stats = await fs.stat(fullPath); if (stats.size > config.maxFileSize) { return { valid: false, reason: `File size (${stats.size} bytes) exceeds maximum allowed size (${config.maxFileSize} bytes)`, size: stats.size }; } return { valid: true, size: stats.size }; } catch (error: any) { return { valid: false, reason: `Cannot access file: ${error.message}` }; } }