summaryrefslogtreecommitdiffstats
path: root/stream.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 /stream.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 'stream.c')
-rw-r--r--stream.c49
1 files changed, 26 insertions, 23 deletions
diff --git a/stream.c b/stream.c
index fe3cc0bb..a2f4baf1 100644
--- a/stream.c
+++ b/stream.c
@@ -1434,7 +1434,7 @@ static struct stdio_mode do_parse_mode(val mode_str, struct stdio_mode m_dfl,
val self)
{
struct stdio_mode m = stdio_mode_init_blank;
- const wchar_t *ms = c_str(default_arg(mode_str, lit("")), self);
+ const wchar_t *ms = c_str(default_arg_strict(mode_str, lit("")), self);
int nredir = 0;
switch (*ms) {
@@ -2917,7 +2917,8 @@ static struct strm_ops record_adapter_ops =
val record_adapter(val regex, val stream, val include_match)
{
val self = lit("record-adapter");
- val rec_adapter = make_delegate_stream(self, default_arg(stream, std_input),
+ val rec_adapter = make_delegate_stream(self,
+ default_arg_strict(stream, std_input),
sizeof (struct record_adapter_base),
&record_adapter_ops.cobj_ops);
struct record_adapter_base *rb = coerce(struct record_adapter_base *,
@@ -2998,7 +2999,7 @@ val clear_error(val stream)
val get_line(val stream_in)
{
val self = lit("get-line");
- val stream = default_arg(stream_in, std_input);
+ val stream = default_arg_strict(stream_in, std_input);
struct strm_ops *ops = coerce(struct strm_ops *,
cobj_ops(self, stream, stream_s));
return ops->get_line(stream);
@@ -3007,7 +3008,7 @@ val get_line(val stream_in)
val get_char(val stream_in)
{
val self = lit("get-char");
- val stream = default_arg(stream_in, std_input);
+ val stream = default_arg_strict(stream_in, std_input);
struct strm_ops *ops = coerce(struct strm_ops *,
cobj_ops(self, stream, stream_s));
return ops->get_char(stream);
@@ -3016,7 +3017,7 @@ val get_char(val stream_in)
val get_byte(val stream_in)
{
val self = lit("get-byte");
- val stream = default_arg(stream_in, std_input);
+ val stream = default_arg_strict(stream_in, std_input);
struct strm_ops *ops = coerce(struct strm_ops *,
cobj_ops(self, stream, stream_s));
return ops->get_byte(stream);
@@ -3024,7 +3025,7 @@ val get_byte(val stream_in)
val get_bytes(val self, val stream_in, mem_t *ptr, ucnum len)
{
- val stream = default_arg(stream_in, std_input);
+ val stream = default_arg_strict(stream_in, std_input);
struct strm_ops *ops = coerce(struct strm_ops *,
cobj_ops(self, stream, stream_s));
return unum(ops->fill_buf(stream, ptr, len, 0));
@@ -3033,7 +3034,7 @@ val get_bytes(val self, val stream_in, mem_t *ptr, ucnum len)
val unget_char(val ch, val stream_in)
{
val self = lit("unget-char");
- val stream = default_arg(stream_in, std_input);
+ val stream = default_arg_strict(stream_in, std_input);
struct strm_ops *ops = coerce(struct strm_ops *,
cobj_ops(self, stream, stream_s));
if (!is_chr(ch))
@@ -3045,7 +3046,7 @@ val unget_byte(val byte, val stream_in)
{
val self = lit("unget-byte");
cnum b = c_num(byte, self);
- val stream = default_arg(stream_in, std_input);
+ val stream = default_arg_strict(stream_in, std_input);
struct strm_ops *ops = coerce(struct strm_ops *,
cobj_ops(self, stream, stream_s));
@@ -3059,8 +3060,8 @@ val unget_byte(val byte, val stream_in)
val put_buf(val buf, val pos_in, val stream_in)
{
val self = lit("put-buf");
- val stream = default_arg(stream_in, std_output);
- ucnum pos = c_unum(default_arg(pos_in, zero), self);
+ val stream = default_arg_strict(stream_in, std_output);
+ ucnum pos = c_unum(default_arg_strict(pos_in, zero), self);
ucnum len = c_unum(length_buf(buf), self);
mem_t *ptr = buf_get(buf, self);
struct strm_ops *ops = coerce(struct strm_ops *,
@@ -3072,8 +3073,8 @@ val put_buf(val buf, val pos_in, val stream_in)
val fill_buf(val buf, val pos_in, val stream_in)
{
val self = lit("fill-buf");
- val stream = default_arg(stream_in, std_input);
- ucnum pos = c_unum(default_arg(pos_in, zero), self);
+ val stream = default_arg_strict(stream_in, std_input);
+ ucnum pos = c_unum(default_arg_strict(pos_in, zero), self);
ucnum len = c_unum(length_buf(buf), self);
mem_t *ptr = buf_get(buf, self);
struct strm_ops *ops = coerce(struct strm_ops *,
@@ -3084,8 +3085,8 @@ val fill_buf(val buf, val pos_in, val stream_in)
val fill_buf_adjust(val buf, val pos_in, val stream_in)
{
val self = lit("fill-buf-adjust");
- val stream = default_arg(stream_in, std_input);
- ucnum pos = c_unum(default_arg(pos_in, zero), self);
+ val stream = default_arg_strict(stream_in, std_input);
+ ucnum pos = c_unum(default_arg_strict(pos_in, zero), self);
val alloc_size = buf_alloc_size(buf);
ucnum len = c_unum(alloc_size, self);
mem_t *ptr = buf_get(buf, self);
@@ -3101,7 +3102,7 @@ val fill_buf_adjust(val buf, val pos_in, val stream_in)
val get_line_as_buf(val stream_in)
{
val self = lit("get-line-as-buf");
- val stream = default_arg(stream_in, std_input);
+ val stream = default_arg_strict(stream_in, std_input);
struct strm_ops *ops = coerce(struct strm_ops *,
cobj_ops(self, stream, stream_s));
val buf = make_buf(zero, nil, num_fast(128));
@@ -3851,7 +3852,7 @@ static val put_indent(val stream, struct strm_ops *ops, cnum chars)
val put_string(val string, val stream_in)
{
val self = lit("put-string");
- val stream = default_arg(stream_in, std_output);
+ val stream = default_arg_strict(stream_in, std_output);
struct strm_base *s = coerce(struct strm_base *, stream->co.handle);
if (lazy_stringp(string)) {
@@ -3894,7 +3895,7 @@ val put_string(val string, val stream_in)
val put_char(val ch, val stream_in)
{
val self = lit("put-char");
- val stream = default_arg(stream_in, std_output);
+ val stream = default_arg_strict(stream_in, std_output);
struct strm_ops *ops = coerce(struct strm_ops *,
cobj_ops(self, stream, stream_s));
struct strm_base *s = coerce(struct strm_base *, stream->co.handle);
@@ -3936,7 +3937,7 @@ val put_char(val ch, val stream_in)
val put_byte(val byte, val stream_in)
{
val self = lit("put-byte");
- val stream = default_arg(stream_in, std_output);
+ val stream = default_arg_strict(stream_in, std_output);
struct strm_ops *ops = coerce(struct strm_ops *,
cobj_ops(self, stream, stream_s));
cnum b = c_num(byte, self);
@@ -3948,9 +3949,11 @@ val put_byte(val byte, val stream_in)
return ops->put_byte(stream, b);
}
-val put_line(val string, val stream)
+val put_line(val string, val stream_in)
{
- return (put_string(default_arg(string, null_string), stream), put_char(chr('\n'), stream));
+ val stream = default_arg_strict(stream_in, std_output);
+ return (put_string(default_arg_strict(string, null_string), stream),
+ put_char(chr('\n'), stream));
}
val put_strings(val strings, val stream)
@@ -3974,7 +3977,7 @@ val put_lines(val lines, val stream)
val flush_stream(val stream_in)
{
val self = lit("flush-stream");
- val stream = default_arg(stream_in, std_output);
+ val stream = default_arg_strict(stream_in, std_output);
struct strm_ops *ops = coerce(struct strm_ops *,
cobj_ops(self, stream, stream_s));
return ops->flush(stream);
@@ -4151,7 +4154,7 @@ struct strm_ctx *get_ctx(val stream)
val get_string(val stream_in, val nchars, val close_after_p)
{
- val stream = default_arg(stream_in, std_input);
+ val stream = default_arg_strict(stream_in, std_input);
val strstream = make_string_output_stream();
nchars = default_null_arg(nchars);
val ch;
@@ -5189,7 +5192,7 @@ val mkdtemp_wrap(val prefix)
val mkstemp_wrap(val prefix, val suffix)
{
val self = lit("mkstemp");
- val suff = default_arg(suffix, null_string);
+ val suff = default_arg_strict(suffix, null_string);
val templ = scat3(prefix, lit("XXXXXX"), suff);
cnum slen = c_num(length(suff), self);
char *tmpl = utf8_dup_to(c_str(templ, self));