summaryrefslogtreecommitdiffstats
path: root/parser.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-07-01 22:17:16 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-07-01 22:17:16 -0700
commitdd3ff4c38db7c9daa72d5074c986a1462ab3bb8e (patch)
treeb06ac035086f1412f799482d5e9fb23e9393afe3 /parser.c
parent0e72e53ef4693e022dbb83b87924ae7470e42e8f (diff)
downloadtxr-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.c41
1 files changed, 18 insertions, 23 deletions
diff --git a/parser.c b/parser.c
index e38b1b85..331e6b7f 100644
--- a/parser.c
+++ b/parser.c
@@ -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);