@@ -69,33 +69,41 @@ public static final IValue serialize(final IValue value, final StringValue absol
6969 }
7070
7171 @ TLAPlusOperator (identifier = "IOExec" , module = "IOUtils" , minLevel = 1 , warn = false )
72- public static Value exec ( final Value command , final Value parameter ) throws IOException , InterruptedException {
72+ public static Value ioExec ( final Value parameter ) throws IOException , InterruptedException {
7373 // 1. Check parameters and covert.
74- if (!(command instanceof StringValue )) {
75- throw new EvalException (EC .TLC_MODULE_ONE_ARGUMENT_ERROR ,
76- new String [] { "IOExec" , "string" , Values .ppr (command .toString ()) });
77- }
7874 if (!(parameter instanceof TupleValue )) {
7975 throw new EvalException (EC .TLC_MODULE_ONE_ARGUMENT_ERROR ,
8076 new String [] { "IOExec" , "sequence" , Values .ppr (parameter .toString ()) });
8177 }
82- final StringValue sv = (StringValue ) command ;
8378 final TupleValue tv = (TupleValue ) parameter ;
84-
85- // 2. Build actual command-line by merging command and parameter.
86- final String cmd = String .format (sv .toUnquotedString (),
87- Arrays .asList (tv .getElems ()).stream ().map (e -> e .toUnquotedString ()).toArray (size -> new Object [size ]));
88-
79+
80+ // 2. Build actual command by converting each parameter element to a string.
81+ // No escaping or quoting is done so the process receives the exact string.
82+ final String [] command = Arrays .asList (tv .getElems ()).stream ()
83+ .map (IOUtils ::convert )
84+ .toArray (size -> new String [size ]);
85+
8986 // 3. Run command-line and receive its output.
90- final Process process = new ProcessBuilder (cmd . split ( " " ) )/*.inheritIO()*/ .start ();
91-
87+ final Process process = new ProcessBuilder (command )/*.inheritIO()*/ .start ();
88+
9289 final StringValue stdout = new StringValue (new String (process .getInputStream ().readAllBytes ()));
9390 final StringValue stderr = new StringValue (new String (process .getErrorStream ().readAllBytes ()));
9491 final IntValue exitCode = IntValue .gen (process .waitFor ());
95-
92+
9693 return new RecordValue (EXEC_NAMES , new Value [] {exitCode , stdout , stderr }, false );
9794 }
9895
96+ private static String convert (IValue v ) {
97+ if (! (v instanceof StringValue )) {
98+ // XXX Proper exception
99+ throw new EvalException (EC .TLC_MODULE_ONE_ARGUMENT_ERROR ,
100+ new String [] { "IOExec" , "sequence" , Values .ppr (v .toString ()) });
101+ }
102+ final StringValue sv = (StringValue ) v ;
103+
104+ return sv .val .toString ();
105+ }
106+
99107 private static final UniqueString EXITVALUE = UniqueString .uniqueStringOf ("exitValue" );
100108 private static final UniqueString STDOUT = UniqueString .uniqueStringOf ("stdout" );
101109 private static final UniqueString STDERR = UniqueString .uniqueStringOf ("stderr" );
0 commit comments