Fix: catch unknown flags in all remaining implementations

Added unknown flag validation to session command in:
awk, clj, cob, erl, ex, f90, forth, fs, lisp, ml, pro, r, scm, tcl, Java

Now all 42+ implementations properly reject unknown flags with
'Unknown option' error instead of making confusing API requests.
This commit is contained in:
Russell Ballestrini 2026-01-04 09:01:39 -05:00
parent 35b3ab615a
commit 09ec15aa62
15 changed files with 126 additions and 11 deletions

View file

@ -877,6 +877,10 @@ public class Un {
result.keyExtend = true;
} else if (!arg.startsWith("-")) {
result.sourceFile = arg;
} else {
System.err.println("Unknown option: " + arg);
printHelp();
System.exit(1);
}
}
return result;

5
un.awk
View file

@ -670,6 +670,11 @@ END {
input_files = input_files ARGV[i + 1]
i += 2
} else {
if (substr(ARGV[i], 1, 1) == "-") {
print "Unknown option: " ARGV[i] > "/dev/stderr"
usage()
exit 1
}
i++
}
}

8
un.clj
View file

@ -526,6 +526,14 @@
(recur (rest args) (first args) env-vars artifacts out-dir network vcpu session-action session-id session-shell session-input-files
service-action service-id service-name service-ports service-bootstrap service-bootstrap-file service-type service-input-files key-extend mode)
;; Unknown option check
(and (= mode :session) (.startsWith (first args) "-"))
(do
(println (str red "Unknown option: " (first args) reset) *err*)
(println "Usage: un.clj session [options]")
(println "Options: --list, --kill ID, --shell SHELL, -s SHELL, -f FILE, -n NETWORK, -v VCPU")
(System/exit 1))
:else
(recur (rest args) file env-vars artifacts out-dir network vcpu session-action session-id session-shell session-input-files
service-action service-id service-name service-ports service-bootstrap service-bootstrap-file service-type service-input-files key-extend mode))))

10
un.cob
View file

@ -376,6 +376,16 @@
ELSE
MOVE WS-ARG3 TO WS-INPUT-FILES
END-IF
ELSE
IF WS-ARG3(1:1) = "-"
STRING "Unknown option: " FUNCTION TRIM(WS-ARG3)
DELIMITED BY SIZE INTO WS-ERROR-MSG
END-STRING
DISPLAY WS-ERROR-MSG UPON SYSERR
DISPLAY "Usage: un.cob session [options]" UPON SYSERR
MOVE 1 TO RETURN-CODE
STOP RUN
END-IF
END-IF
ACCEPT WS-ARG3 FROM ARGUMENT-VALUE
END-PERFORM.

17
un.erl
View file

@ -103,6 +103,7 @@ session_command(["--kill", SessionId | _]) ->
io:format("\033[32mSession terminated: ~s\033[0m~n", [SessionId]);
session_command(Args) ->
validate_session_args(Args),
ApiKey = get_api_key(),
Shell = get_shell_opt(Args, "bash"),
InputFiles = get_input_files(Args),
@ -114,6 +115,22 @@ session_command(Args) ->
io:format("\033[33mSession created (WebSocket required)\033[0m~n"),
io:format("~s~n", [Response]).
validate_session_args([]) -> ok;
validate_session_args(["--shell", _ | Rest]) -> validate_session_args(Rest);
validate_session_args(["-s", _ | Rest]) -> validate_session_args(Rest);
validate_session_args(["-f", _ | Rest]) -> validate_session_args(Rest);
validate_session_args(["-n", _ | Rest]) -> validate_session_args(Rest);
validate_session_args(["-v", _ | Rest]) -> validate_session_args(Rest);
validate_session_args([Arg | _]) ->
case Arg of
[$- | _] ->
io:format(standard_error, "Unknown option: ~s~n", [Arg]),
io:format(standard_error, "Usage: un.erl session [options]~n", []),
halt(1);
_ ->
validate_session_args([])
end.
%% Service command
service_command(["--list" | _]) ->
ApiKey = get_api_key(),

17
un.ex
View file

@ -133,6 +133,7 @@ defmodule Un do
end
defp session_command(args) do
validate_session_args(args)
api_key = get_api_key()
shell = get_opt(args, "--shell", "-s", "bash")
network = get_opt(args, "-n", nil, nil)
@ -149,6 +150,22 @@ defmodule Un do
IO.puts(response)
end
defp validate_session_args([]), do: :ok
defp validate_session_args(["--shell", _ | rest]), do: validate_session_args(rest)
defp validate_session_args(["-s", _ | rest]), do: validate_session_args(rest)
defp validate_session_args(["-f", _ | rest]), do: validate_session_args(rest)
defp validate_session_args(["-n", _ | rest]), do: validate_session_args(rest)
defp validate_session_args(["-v", _ | rest]), do: validate_session_args(rest)
defp validate_session_args([arg | _]) do
if String.starts_with?(arg, "-") do
IO.puts(:stderr, "Unknown option: #{arg}")
IO.puts(:stderr, "Usage: un.ex session [options]")
System.halt(1)
else
validate_session_args([])
end
end
# Service command
defp service_command(["--list" | _]) do
api_key = get_api_key()

8
un.f90
View file

@ -222,6 +222,14 @@ contains
input_files = trim(arg)
end if
end if
else
if (len_trim(arg) > 0) then
if (arg(1:1) == '-') then
write(0, '(A,A)') 'Unknown option: ', trim(arg)
write(0, '(A)') 'Usage: un.f90 session [options]'
stop 1
end if
end if
end if
end do

View file

@ -627,9 +627,17 @@
0 (bye)
then
\ Check if argument starts with '-'
2dup drop c@ [char] - = if
s" Unknown option: " type type cr
s" Usage: un.forth session [options]" type cr
2drop
1 (bye)
then
2drop
s" Error: Use --list or --kill ID" type cr
1 (bye)
session-create
0 (bye)
;
\ Handle service subcommand

6
un.fs
View file

@ -636,7 +636,11 @@ let parseArgs (argv: string[]) =
| "--dump-file" -> i <- i + 1; args.ServiceDumpFile <- Some argv.[i]
| "--extend" -> args.KeyExtend <- true
| arg when not (arg.StartsWith("-")) -> args.SourceFile <- Some arg
| _ -> ()
| arg ->
if arg.StartsWith("-") && args.Command = Some "session" then
eprintfn "Unknown option: %s" arg
eprintfn "Usage: un.fs session [options]"
Environment.Exit(1)
i <- i + 1
args

View file

@ -434,7 +434,12 @@
do (let ((opt (nth i rest-args))
(val (nth (1+ i) rest-args)))
(cond
((or (string= opt "--shell") (string= opt "-s")) (setf shell val)))))
((or (string= opt "--shell") (string= opt "-s")) (setf shell val))
((string= opt "-f") nil) ; already parsed
((and (> (length opt) 0) (char= (char opt 0) #\-))
(format *error-output* "Unknown option: ~a~%" opt)
(format *error-output* "Usage: un.lisp session [options]~%")
(uiop:quit 1)))))
(session-cmd "create" nil shell input-files)))))
((string= (first args) "service")
(cond

8
un.ml
View file

@ -664,7 +664,13 @@ let () =
| "-n" :: net :: rest -> parse_session action shell (Some net) vcpu rest
| "-v" :: v :: rest -> parse_session action shell network (Some (int_of_string v)) rest
| "-f" :: _ :: rest -> parse_session action shell network vcpu rest (* skip -f, already parsed *)
| _ :: rest -> parse_session action shell network vcpu rest
| arg :: rest ->
if String.length arg > 0 && arg.[0] = '-' then begin
Printf.fprintf stderr "Unknown option: %s\n" arg;
Printf.fprintf stderr "Usage: un.ml session [options]\n";
exit 1
end else
parse_session action shell network vcpu rest
in
parse_session "create" None None None rest
| "service" :: rest ->

9
un.pro
View file

@ -321,8 +321,13 @@ parse_session_args(['-f', FilePath|Rest], Shell, Files, ShellOut, InputFiles) :-
; format(user_error, 'Error: File not found: ~w~n', [FilePath]),
halt(1)
).
parse_session_args([_|Rest], Shell, Files, ShellOut, InputFiles) :-
parse_session_args(Rest, Shell, Files, ShellOut, InputFiles).
parse_session_args([Arg|Rest], Shell, Files, ShellOut, InputFiles) :-
( atom_chars(Arg, ['-'|_])
-> format(user_error, 'Unknown option: ~w~n', [Arg]),
format(user_error, 'Usage: un.pro session [options]~n', []),
halt(1)
; parse_session_args(Rest, Shell, Files, ShellOut, InputFiles)
).
% Handle service subcommand
handle_service(Args) :-

6
un.r
View file

@ -702,7 +702,11 @@ parse_args <- function() {
result$source_file <- arg
i <- i + 1
} else {
cat(sprintf("Unknown argument: %s\n", arg), file = stderr())
cat(sprintf("Unknown option: %s\n", arg), file = stderr())
cat("Usage: un.r [options] <source_file>\n", file = stderr())
cat(" un.r session [options]\n", file = stderr())
cat(" un.r service [options]\n", file = stderr())
cat(" un.r key [options]\n", file = stderr())
quit(status = 1)
}
}

13
un.scm
View file

@ -481,10 +481,17 @@
(shell #f))
;; Parse --shell option
(let loop ((args rest-args))
(when (and (pair? args) (pair? (cdr args)))
(when (pair? args)
(cond
((or (equal? (car args) "--shell") (equal? (car args) "-s"))
(set! shell (cadr args)))
((and (or (equal? (car args) "--shell") (equal? (car args) "-s")) (pair? (cdr args)))
(set! shell (cadr args))
(loop (cddr args)))
((equal? (car args) "-f")
(loop (cdr args))) ; skip -f, already parsed
((and (string? (car args)) (> (string-length (car args)) 0) (char=? (string-ref (car args) 0) #\-))
(format (current-error-port) "~aUnknown option: ~a~a\n" red (car args) reset)
(format (current-error-port) "Usage: un.scm session [options]\n")
(exit 1))
(else (loop (cdr args))))))
(session-cmd "create" #f shell input-files)))))
((equal? (car args) "service")

7
un.tcl
View file

@ -348,6 +348,13 @@ proc cmd_session {args} {
incr i
lappend input_files [lindex $args $i]
}
default {
if {[string index $arg 0] eq "-"} {
puts stderr "${::RED}Unknown option: $arg${::RESET}"
puts stderr "Usage: un.tcl session \[options\]"
exit 1
}
}
}
}