MCPcopy
hub / github.com/codeaashu/claude-code / validateInput

Function validateInput

src/tools/FileReadTool/FileReadTool.ts:418–495  ·  view source on GitHub ↗
({ file_path, pages }, toolUseContext: ToolUseContext)

Source from the content-addressed store, hash-verified

416 },
417 renderToolUseErrorMessage,
418 async validateInput({ file_path, pages }, toolUseContext: ToolUseContext) {
419 // Validate pages parameter (pure string parsing, no I/O)
420 if (pages !== undefined) {
421 const parsed = parsePDFPageRange(pages)
422 if (!parsed) {
423 return {
424 result: false,
425 message: `Invalid pages parameter: "${pages}". Use formats like "1-5", "3", or "10-20". Pages are 1-indexed.`,
426 errorCode: 7,
427 }
428 }
429 const rangeSize =
430 parsed.lastPage === Infinity
431 ? PDF_MAX_PAGES_PER_READ + 1
432 : parsed.lastPage - parsed.firstPage + 1
433 if (rangeSize > PDF_MAX_PAGES_PER_READ) {
434 return {
435 result: false,
436 message: `Page range "${pages}" exceeds maximum of ${PDF_MAX_PAGES_PER_READ} pages per request. Please use a smaller range.`,
437 errorCode: 8,
438 }
439 }
440 }
441
442 // Path expansion + deny rule check (no I/O)
443 const fullFilePath = expandPath(file_path)
444
445 const appState = toolUseContext.getAppState()
446 const denyRule = matchingRuleForInput(
447 fullFilePath,
448 appState.toolPermissionContext,
449 'read',
450 'deny',
451 )
452 if (denyRule !== null) {
453 return {
454 result: false,
455 message:
456 'File is in a directory that is denied by your permission settings.',
457 errorCode: 1,
458 }
459 }
460
461 // SECURITY: UNC path check (no I/O) — defer filesystem operations
462 // until after user grants permission to prevent NTLM credential leaks
463 const isUncPath =
464 fullFilePath.startsWith('\\\\') || fullFilePath.startsWith('//')
465 if (isUncPath) {
466 return { result: true }
467 }
468
469 // Binary extension check (string check on extension only, no I/O).
470 // PDF, images, and SVG are excluded - this tool renders them natively.
471 const ext = path.extname(fullFilePath).toLowerCase()
472 if (
473 hasBinaryExtension(fullFilePath) &&
474 !isPDFExtension(ext) &&
475 !IMAGE_EXTENSIONS.has(ext.slice(1))

Callers

nothing calls this directly

Calls 7

parsePDFPageRangeFunction · 0.85
expandPathFunction · 0.85
matchingRuleForInputFunction · 0.85
hasBinaryExtensionFunction · 0.85
isPDFExtensionFunction · 0.85
isBlockedDevicePathFunction · 0.85
hasMethod · 0.45

Tested by

no test coverage detected