summaryrefslogtreecommitdiffstats
path: root/stream.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-03-30 10:20:14 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-03-30 10:20:14 -0700
commit8f6422ad7c34d07d7ff81384e789168fa6c10759 (patch)
tree61782a51ea4916ddc4c22242d968de15d1cc132b /stream.c
parent91f94cfd8e003f7ed4bcbca55943a9f588ecc576 (diff)
downloadtxr-8f6422ad7c34d07d7ff81384e789168fa6c10759.tar.gz
txr-8f6422ad7c34d07d7ff81384e789168fa6c10759.tar.bz2
txr-8f6422ad7c34d07d7ff81384e789168fa6c10759.zip
string output streams: null pointer deref.
Originally, string output streams would null out their handle when the string was extracted. This changed in commit e44c113ee17c7cf15e8b1891f4d51ec03b16bc24 [Jul 2015], so that just the string buffer was nulled out. Unfortunately, two places in the code were not updated, still checking for a null handle, which is always false, and not defending against the null handle. * stream.c (string_out_extracted_error): New static function. (string_out_put_string, string_out_put_byte): Check the buffer for null, not the handle, which doesn't go null while the object is live. Throw an exception rather than returning nil.
Diffstat (limited to 'stream.c')
-rw-r--r--stream.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/stream.c b/stream.c
index 20dbaebf..56563c0c 100644
--- a/stream.c
+++ b/stream.c
@@ -2065,6 +2065,12 @@ static int string_out_byte_callback(mem_t *ctx)
return so->byte_buf[so->tail++];
}
+static void string_out_extracted_error(val stream)
+{
+ uw_throwf(file_error_s, lit("output not possible on ~s: string extracted"),
+ stream, nao);
+}
+
static val string_out_put_char(val stream, val ch);
static val string_out_byte_flush(struct string_out *so, val stream)
@@ -2091,8 +2097,8 @@ static val string_out_put_string(val stream, val str)
{
struct string_out *so = coerce(struct string_out *, stream->co.handle);
- if (so == 0)
- return nil;
+ if (so->buf == 0)
+ string_out_extracted_error(stream);
while (so->head != so->tail)
string_out_byte_flush(so, stream);
@@ -2136,8 +2142,8 @@ static val string_out_put_byte(val stream, int ch)
{
struct string_out *so = coerce(struct string_out *, stream->co.handle);
- if (so == 0)
- return nil;
+ if (so->buf == 0)
+ string_out_extracted_error(stream);
so->byte_buf[so->head++] = ch;