checkInputSafety function

List<String> checkInputSafety(
  1. String input
)

Check for potentially harmful input patterns.

Implementation

List<String> checkInputSafety(String input) {
  final warnings = <String>[];

  // Check for common prompt injection patterns.
  final injectionPatterns = <RegExp, String>{
    RegExp(
      r'ignore\s+(all\s+)?previous\s+instructions',
      caseSensitive: false,
    ): 'Potential prompt injection: "ignore previous instructions" pattern detected.',
    RegExp(r'you\s+are\s+now\s+(?:a|an|in)\s+', caseSensitive: false):
        'Potential prompt injection: role reassignment pattern detected.',
    RegExp(r'system\s*:\s*', caseSensitive: false):
        'Potential prompt injection: system message impersonation detected.',
    RegExp(r'<\s*(?:system|admin|root)\s*>', caseSensitive: false):
        'Potential prompt injection: system/admin tag detected.',
    RegExp(
      r'(?:ADMIN|SYSTEM|ROOT)\s*(?:MODE|ACCESS|OVERRIDE)',
      caseSensitive: false,
    ): 'Potential prompt injection: privilege escalation pattern detected.',
    RegExp(r'forget\s+(?:everything|all|your)\s+', caseSensitive: false):
        'Potential prompt injection: memory reset pattern detected.',
    RegExp(r'(?:execute|run|eval)\s*\(', caseSensitive: false):
        'Potential code execution pattern detected.',
  };

  for (final entry in injectionPatterns.entries) {
    if (entry.key.hasMatch(input)) {
      warnings.add(entry.value);
    }
  }

  // Check for very long single lines (possible binary data or minified code).
  final lines = input.split('\n');
  for (var i = 0; i < lines.length; i++) {
    if (lines[i].length > 10000) {
      warnings.add(
        'Line ${i + 1} is very long (${lines[i].length} characters). '
        'This may be minified code or binary data.',
      );
      break; // Only warn once.
    }
  }

  // Check for excessive repetition.
  if (input.length > 100) {
    final sample = input.substring(0, input.length.clamp(0, 1000));
    final words = sample.split(RegExp(r'\s+'));
    if (words.length > 10) {
      final freq = <String, int>{};
      for (final w in words) {
        freq[w] = (freq[w] ?? 0) + 1;
      }
      final maxFreq = freq.values.fold(0, (a, b) => a > b ? a : b);
      if (maxFreq > words.length * 0.5) {
        warnings.add(
          'Input contains excessive repetition, which may indicate '
          'garbled or auto-generated text.',
        );
      }
    }
  }

  // Check for null bytes or other control characters.
  if (RegExp(r'[\x00-\x08\x0e-\x1f]').hasMatch(input)) {
    warnings.add(
      'Input contains control characters that may indicate binary data.',
    );
  }

  return warnings;
}