Skip to content

Commit 7f8ae74

Browse files
committed
fix: proper arguments serialization
1 parent 534c0d0 commit 7f8ae74

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

lib/src/scripts_parser/events/execution/command_executed.dart

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:collection/collection.dart';
12
import 'package:rps/rps.dart';
23
import 'dart:math' as math;
34

@@ -29,6 +30,21 @@ class CommandExecuted extends ExecutionEvent {
2930
this.error,
3031
}) : arguments = arguments ?? const [];
3132

33+
/// Escape backslashes, single and double quotes for shell safety
34+
/// and enclose in quotes only if necessary: contains spaces or quotes
35+
String? _serializeArguments(List<String> arguments) {
36+
if (arguments.isEmpty) return null;
37+
38+
return arguments.map((arg) {
39+
String escaped = arg.replaceAll(r'\', r'\\').replaceAll('"', r'\"').replaceAll("'", r"\'");
40+
41+
if (escaped != arg) {
42+
return '"$escaped"';
43+
}
44+
return escaped;
45+
}).join(' ');
46+
}
47+
3248
/// Compiles the command. Returns the command ready for execution.
3349
String compile() {
3450
final argumentsInCommand = _positionalArgumentsRegexp.allMatches(command);
@@ -75,9 +91,9 @@ class CommandExecuted extends ExecutionEvent {
7591
);
7692
}
7793

78-
return [filledCommand, ...arguments.sublist(lastUsed + 1)].join(' ');
94+
return [filledCommand, _serializeArguments(arguments.sublist(lastUsed + 1))].whereNotNull().join(' ');
7995
} else {
80-
return [command, ...arguments].join(' ');
96+
return [command, _serializeArguments(arguments)].whereNotNull().join(' ');
8197
}
8298
}
8399

0 commit comments

Comments
 (0)