diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-12-09 21:51:45 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-12-09 21:51:45 -0800 |
commit | 4632c71d8f883fa5a4b208673b1b36e83e3e8c41 (patch) | |
tree | 592529a51cd5b0ce0e38e92094fe3057263b6e4d /stream.c | |
parent | 2ea79e9094475dfe36f9291d98765dfb74151155 (diff) | |
download | txr-4632c71d8f883fa5a4b208673b1b36e83e3e8c41.tar.gz txr-4632c71d8f883fa5a4b208673b1b36e83e3e8c41.tar.bz2 txr-4632c71d8f883fa5a4b208673b1b36e83e3e8c41.zip |
Bugfix: crash in get_line.
Incorrect, irrelevant handle test inside stdio_get_line
virtual function fails to detect closed stream, leading
to a null pointer passed to the stdio library.
* stream.c (snarf_line): Rewrite according to pattern
followed by the other functions. We must test h->f for
null, not stream->co.handle, which never goes null
until the object is being reclaimed by gc.
Diffstat (limited to 'stream.c')
-rw-r--r-- | stream.c | 14 |
1 files changed, 6 insertions, 8 deletions
@@ -584,16 +584,14 @@ static wchar_t *snarf_line(struct stdio_handle *h) static val stdio_get_line(val stream) { - errno = 0; - if (stream->co.handle == 0) { - return stdio_maybe_read_error(stream); - } else { - struct stdio_handle *h = coerce(struct stdio_handle *, stream->co.handle); + struct stdio_handle *h = coerce(struct stdio_handle *, stream->co.handle); + if (h->f) { wchar_t *line = snarf_line(h); - if (!line) - return stdio_maybe_read_error(stream); - return string_own(line); + if (line) + return string_own(line); } + + return stdio_maybe_read_error(stream); } static val stdio_get_char(val stream) |