Skip to main content
Glama
sanitization.test.tsโ€ข7.67 kB
/** * Unit tests for input sanitization utilities */ import { sanitizeForLike, validateFilePath, sanitizeProjectPath, sanitizeSQLIdentifier, pathToProjectFolderName, } from '../../utils/sanitization.js'; describe('sanitization utilities', () => { describe('sanitizeForLike', () => { it('should escape % characters', () => { expect(sanitizeForLike('test%file')).toBe('test\\%file'); }); it('should escape _ characters', () => { expect(sanitizeForLike('test_file')).toBe('test\\_file'); }); it('should escape " characters', () => { expect(sanitizeForLike('test"file')).toBe('test\\"file'); }); it('should escape \\ characters', () => { expect(sanitizeForLike('test\\file')).toBe('test\\\\file'); }); it('should escape multiple special characters', () => { expect(sanitizeForLike('test%_"\\file')).toBe('test\\%\\_\\"\\\\file'); }); it('should handle strings without special characters', () => { expect(sanitizeForLike('normalfile')).toBe('normalfile'); }); it('should handle empty strings', () => { expect(sanitizeForLike('')).toBe(''); }); }); describe('validateFilePath', () => { it('should accept valid file paths', () => { expect(validateFilePath('/Users/test/file.txt')).toBe('/Users/test/file.txt'); expect(validateFilePath('src/auth/token.ts')).toBe('src/auth/token.ts'); }); it('should remove null bytes', () => { expect(validateFilePath('test\0file')).toBe('testfile'); }); it('should reject path traversal with ..', () => { expect(() => validateFilePath('../etc/passwd')).toThrow('Path traversal detected'); expect(() => validateFilePath('test/../secret')).toThrow('Path traversal detected'); }); it('should reject access to system directories', () => { expect(() => validateFilePath('/etc/passwd')).toThrow('system directories'); expect(() => validateFilePath('/sys/kernel')).toThrow('system directories'); expect(() => validateFilePath('/proc/cpuinfo')).toThrow('system directories'); }); it('should allow relative paths', () => { expect(validateFilePath('src/index.ts')).toBe('src/index.ts'); }); }); describe('sanitizeProjectPath', () => { it('should accept valid project paths', () => { expect(sanitizeProjectPath('/Users/test/project')).toBe('/Users/test/project'); }); it('should remove null bytes', () => { expect(sanitizeProjectPath('/path\0/project')).toBe('/path/project'); }); it('should reject path traversal', () => { expect(() => sanitizeProjectPath('../secret')).toThrow('Path traversal detected'); }); it('should normalize multiple slashes', () => { expect(sanitizeProjectPath('/path//to///project')).toBe('/path/to/project'); }); it('should remove trailing slashes', () => { expect(sanitizeProjectPath('/path/to/project/')).toBe('/path/to/project'); }); it('should handle absolute paths', () => { expect(sanitizeProjectPath('/absolute/path')).toBe('/absolute/path'); }); }); describe('sanitizeSQLIdentifier', () => { it('should accept valid SQL identifiers', () => { expect(sanitizeSQLIdentifier('table_name')).toBe('table_name'); expect(sanitizeSQLIdentifier('Column123')).toBe('Column123'); expect(sanitizeSQLIdentifier('_private')).toBe('_private'); }); it('should reject identifiers starting with numbers', () => { expect(() => sanitizeSQLIdentifier('123table')).toThrow('Invalid SQL identifier'); }); it('should reject identifiers with special characters', () => { expect(() => sanitizeSQLIdentifier('table-name')).toThrow('Invalid SQL identifier'); expect(() => sanitizeSQLIdentifier('table.name')).toThrow('Invalid SQL identifier'); expect(() => sanitizeSQLIdentifier('table name')).toThrow('Invalid SQL identifier'); }); it('should reject empty identifiers', () => { expect(() => sanitizeSQLIdentifier('')).toThrow('Invalid SQL identifier'); }); it('should accept identifiers with underscores', () => { expect(sanitizeSQLIdentifier('my_table_name')).toBe('my_table_name'); }); }); describe('Windows path handling', () => { describe('pathToProjectFolderName - Windows paths', () => { it('should handle Windows absolute paths with drive letter', () => { const result = pathToProjectFolderName('C:\\Users\\user\\project'); expect(result).toBe('C-Users-user-project'); }); it('should handle Windows paths with lowercase drive letter', () => { const result = pathToProjectFolderName('c:\\users\\user\\project'); expect(result).toBe('c-users-user-project'); }); it('should handle Windows UNC paths', () => { const result = pathToProjectFolderName('\\\\server\\share\\project'); expect(result).toBe('-server-share-project'); }); it('should handle mixed forward and backward slashes', () => { const result = pathToProjectFolderName('C:\\Users/user\\github/project'); expect(result).toBe('C-Users-user-github-project'); }); it('should handle multiple consecutive backslashes', () => { const result = pathToProjectFolderName('C:\\\\Users\\\\\\project'); expect(result).toBe('C-Users-project'); }); }); describe('sanitizeProjectPath - Windows normalization', () => { it('should normalize Windows paths with multiple backslashes', () => { const result = sanitizeProjectPath('C:\\path\\\\to\\\\\\project'); // Result will be platform-specific, just verify no error expect(result).toBeTruthy(); expect(result).not.toContain('\\\\\\'); }); it('should remove trailing backslashes on Windows-style paths', () => { const result = sanitizeProjectPath('C:\\path\\to\\project\\'); expect(result.endsWith('\\')).toBe(false); expect(result.endsWith('/')).toBe(false); }); }); describe('validateFilePath - Windows system directories', () => { // Mock Windows platform for testing const originalPlatform = process.platform; beforeEach(() => { Object.defineProperty(process, 'platform', { value: 'win32', writable: true, configurable: true, }); }); afterEach(() => { Object.defineProperty(process, 'platform', { value: originalPlatform, writable: true, configurable: true, }); }); it('should reject Windows system directories', () => { expect(() => validateFilePath('C:\\Windows\\System32')).toThrow('system directories'); expect(() => validateFilePath('C:\\Windows\\notepad.exe')).toThrow('system directories'); }); it('should reject Program Files directory', () => { expect(() => validateFilePath('C:\\Program Files\\app')).toThrow('system directories'); }); it('should reject ProgramData directory', () => { expect(() => validateFilePath('C:\\ProgramData\\config')).toThrow('system directories'); }); it('should allow user directories on Windows', () => { expect(validateFilePath('C:\\Users\\user\\project\\file.txt')) .toBe('C:\\Users\\user\\project\\file.txt'); }); it('should be case-insensitive for Windows paths', () => { expect(() => validateFilePath('c:\\windows\\system32')).toThrow('system directories'); expect(() => validateFilePath('C:\\WINDOWS\\System32')).toThrow('system directories'); }); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/xiaolai/claude-writers-aid-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server