diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-03-09 20:30:06 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-03-09 20:30:06 -0800 |
commit | 0ceb62ad1eddfdc0ade20005829c845afec67d81 (patch) | |
tree | 268f8b7e90dc4afa4bae6474e4df8446a29fd8d0 | |
parent | 4d0cdf070aa173c6e4ca23ff05e00a5f1731efa5 (diff) | |
download | txr-0ceb62ad1eddfdc0ade20005829c845afec67d81.tar.gz txr-0ceb62ad1eddfdc0ade20005829c845afec67d81.tar.bz2 txr-0ceb62ad1eddfdc0ade20005829c845afec67d81.zip |
Don't open streams or stdin on non-matching directives.
* match.c (open_data_source): The logic of not opening
the data source for a non-matching directive must be applied
to streams also, because the lazy list mechanism will read
ahead from an underlying non-interactive stream. We must
also apply it in the case when we open standard input by
default. If standard input is non-interactive such that the
lazy list unconditionally tries to read a line from it
upon construction, we misbehave. The program could block
on the read. Even if it doesn't block, the input action is
an unwanted externally visible event.
-rw-r--r-- | match.c | 47 |
1 files changed, 25 insertions, 22 deletions
@@ -4382,6 +4382,10 @@ static val h_assert(match_line_ctx *c) static void open_data_source(match_files_ctx *c) { spec_bind (specline, first_spec, c->spec); + int non_matching_dir = (consp(first_spec) && + (gethash(non_matching_directive_table, + first(first_spec))) && + !rest(specline)); /* c->data == t is set up by the top level call to match_files. * It indicates that we have not yet opened any data source. @@ -4393,32 +4397,27 @@ static void open_data_source(match_files_ctx *c) val name = ss_consp ? cdr(source_spec) : source_spec; val nothrow = tnil(ss_consp && car(source_spec) == nothrow_k); - if (stringp(name)) { - if (consp(first_spec) && - (gethash(non_matching_directive_table, first(first_spec))) && - !rest(specline)) - { - debuglf(first_spec, lit("not opening source ~a " - "since query starts with non-matching " - "directive."), name, nao); - } else { - val stream = complex_open(name, nil, nil, nothrow, t); + if (non_matching_dir) { + debuglf(first_spec, lit("not opening source ~a " + "since query starts with non-matching " + "directive."), name, nao); + } else if (stringp(name)) { + val stream = complex_open(name, nil, nil, nothrow, t); - debuglf(specline, lit("opening data source ~a"), name, nao); + debuglf(specline, lit("opening data source ~a"), name, nao); - if (!stream) { - debuglf(first_spec, lit("could not open ~a: " - "treating as failed match due to nothrow"), name, nao); - c->data = nil; - return; - } + if (!stream) { + debuglf(first_spec, lit("could not open ~a: " + "treating as failed match due to nothrow"), name, nao); + c->data = nil; + return; + } - c->files = cons(name, cdr(c->files)); /* Get rid of cons and nothrow */ - c->curfile = source_spec; + c->files = cons(name, cdr(c->files)); /* Get rid of cons and nothrow */ + c->curfile = source_spec; - if ((c->data = lazy_stream_cons(stream)) != nil) - c->data_lineno = one; - } + if ((c->data = lazy_stream_cons(stream)) != nil) + c->data_lineno = one; } else if (streamp(name)) { if ((c->data = lazy_stream_cons(name))) c->data_lineno = one; @@ -4428,6 +4427,10 @@ static void open_data_source(match_files_ctx *c) } else if (c->data == t && c->files == nil) { if (opt_compat && opt_compat <= 170) { c->data = nil; + } else if (non_matching_dir) { + debuglf(first_spec, lit("not opening standard input " + "since query starts with non-matching " + "directive."), nao); } else { debuglf(first_spec, lit("opening standard input as data source"), nao); c->curfile = lit("-"); |