diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-07-01 22:17:16 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-07-01 22:17:16 -0700 |
commit | dd3ff4c38db7c9daa72d5074c986a1462ab3bb8e (patch) | |
tree | b06ac035086f1412f799482d5e9fb23e9393afe3 /parser.c | |
parent | 0e72e53ef4693e022dbb83b87924ae7470e42e8f (diff) | |
download | txr-dd3ff4c38db7c9daa72d5074c986a1462ab3bb8e.tar.gz txr-dd3ff4c38db7c9daa72d5074c986a1462ab3bb8e.tar.bz2 txr-dd3ff4c38db7c9daa72d5074c986a1462ab3bb8e.zip |
streams: tightening sloppy argument defaulting.
Numerous functions in TXR Lisp treat a nil argument for an
optional parameter as if it were omitted. In the case of
streams, this can cause problems. An accidental nil passed to
an input function can cause it to read from standard input and
hang. In this patch, argument defaulting is tighented for
functions that perform I/O. It's mostly stream parameters, but
not exclusively.
* eval.c (prinl, pprinl): Use default_arg_strict to default
the stream argument, and also re-use that value for the
put_char call.
* lib.c (lazy_stream_cons, print, pprint, put_json): Use
default_arg_strict rather than default_arg.
* parser.c (regex_parse, lisp_parse_impl, txr_parse): Tighten
the defaulting of the input stream and error stream arguments,
streamlining the logic at the same time.
* stream.c (do_parse_mode): Use default_arg_strict for the
mode string argument.
(record_adapter, get_line, get_char, get_byte, get_bytes,
unget_byte, put_buf, fill_buf, fill_buf_adjust,
get_line_as_buf, put_string, put_char, put_byte, put_line,
flush_stream, get_string): Use strict defaulting for stream
argument.
(mkstemp_wrap): Use strict defaulting for suffix.
Diffstat (limited to 'parser.c')
-rw-r--r-- | parser.c | 41 |
1 files changed, 18 insertions, 23 deletions
@@ -604,13 +604,12 @@ found: val regex_parse(val string, val error_stream) { - uses_or2; val save_stream = std_error; val stream = make_string_byte_input_stream(string); parser_t parser; - error_stream = default_null_arg(error_stream); - std_error = if3(error_stream == t, std_output, or2(error_stream, std_null)); + error_stream = default_arg_strict(error_stream, std_null); + std_error = if3(error_stream == t, std_output, error_stream); parser_common_init(&parser); parser.stream = stream; @@ -635,16 +634,13 @@ static val lisp_parse_impl(val self, enum prime_parser prime, val error_stream, val error_return_val, val name_in, val lineno) { - uses_or2; - val source = default_null_arg(source_in); + val source = default_arg_strict(source_in, std_input); val str = stringp(source); - val input_stream = if3(str, - make_string_byte_input_stream(source), - or2(source, std_input)); - val name = or2(default_null_arg(name_in), - if3(str, - lit("string"), - stream_get_prop(input_stream, name_k))); + val input_stream = if3(str, make_string_byte_input_stream(source), source); + val name = default_arg_strict(name_in, + if3(str, + lit("string"), + stream_get_prop(input_stream, name_k))); val parser = ensure_parser(input_stream, name); val saved_dyn = dyn_env; parser_t *pi = parser_get_impl(self, parser); @@ -657,8 +653,8 @@ static val lisp_parse_impl(val self, enum prime_parser prime, dyn_env = make_env(nil, nil, dyn_env); - error_stream = default_null_arg(error_stream); - error_stream = if3(error_stream == t, std_output, or2(error_stream, std_null)); + error_stream = default_arg_strict(error_stream, std_null); + error_stream = if3(error_stream == t, std_output, error_stream); class_check (self, error_stream, stream_s); if (lineno && !missingp(lineno)) @@ -814,16 +810,15 @@ val read_compiled_file(val self, val stream, val error_stream) val txr_parse(val source_in, val error_stream, val error_return_val, val name_in) { - uses_or2; val self = lit("txr-parse"); - val source = default_null_arg(source_in); + val source = default_arg_strict(source_in, std_input); val input_stream = if3(stringp(source), make_string_byte_input_stream(source), - or2(source, std_input)); - val name = or2(default_null_arg(name_in), - if3(stringp(source), - lit("string"), - stream_get_prop(input_stream, name_k))); + source); + val name = default_arg_strict(name_in, + if3(stringp(source), + lit("string"), + stream_get_prop(input_stream, name_k))); int gc = gc_state(0); val saved_dyn = dyn_env; val parser_obj = ensure_parser(input_stream, name); @@ -833,8 +828,8 @@ val txr_parse(val source_in, val error_stream, uw_simple_catch_begin; dyn_env = make_env(nil, nil, dyn_env); - error_stream = default_null_arg(error_stream); - error_stream = if3(error_stream == t, std_output, or2(error_stream, std_null)); + error_stream = default_arg_strict(error_stream, std_null); + error_stream = if3(error_stream == t, std_output, error_stream); class_check (self, error_stream, stream_s); parse_once(self, input_stream, name); |