DetectAndReadInput robustly detects whether input is a file path or direct SQL and returns the SQL content with proper validation and security limits.
(input string)
| 55 | // DetectAndReadInput robustly detects whether input is a file path or direct SQL |
| 56 | // and returns the SQL content with proper validation and security limits. |
| 57 | func DetectAndReadInput(input string) (*InputResult, error) { |
| 58 | if input == "" { |
| 59 | return nil, fmt.Errorf("empty input provided") |
| 60 | } |
| 61 | |
| 62 | input = strings.TrimSpace(input) |
| 63 | |
| 64 | _, statErr := os.Stat(input) |
| 65 | if statErr == nil { |
| 66 | if err := validate.ValidateInputFile(input); err != nil { |
| 67 | return nil, fmt.Errorf("security validation failed: %w", err) |
| 68 | } |
| 69 | |
| 70 | content, err := os.ReadFile(input) // #nosec G304 |
| 71 | if err != nil { |
| 72 | return nil, fmt.Errorf("failed to read file %s: %w", input, err) |
| 73 | } |
| 74 | |
| 75 | if len(content) == 0 { |
| 76 | return nil, fmt.Errorf("file is empty: %s", input) |
| 77 | } |
| 78 | |
| 79 | return &InputResult{ |
| 80 | Type: InputTypeFile, |
| 81 | Content: content, |
| 82 | Source: input, |
| 83 | }, nil |
| 84 | } |
| 85 | |
| 86 | if strings.Contains(input, string(filepath.Separator)) || strings.HasSuffix(strings.ToLower(input), ".sql") { |
| 87 | return nil, fmt.Errorf("invalid file path: %w", statErr) |
| 88 | } |
| 89 | |
| 90 | if !LooksLikeSQL(input) { |
| 91 | return nil, fmt.Errorf("input does not appear to be valid SQL or a file path: %s", input) |
| 92 | } |
| 93 | |
| 94 | if len(input) > MaxFileSize { |
| 95 | return nil, fmt.Errorf("SQL query too long: %d characters (max %d)", len(input), MaxFileSize) |
| 96 | } |
| 97 | |
| 98 | return &InputResult{ |
| 99 | Type: InputTypeSQL, |
| 100 | Content: []byte(input), |
| 101 | Source: "direct input", |
| 102 | }, nil |
| 103 | } |
| 104 | |
| 105 | // IsValidSQLFileExtension checks if the file extension is acceptable for SQL. |
| 106 | func IsValidSQLFileExtension(ext string) bool { |
no test coverage detected