From 8f6422ad7c34d07d7ff81384e789168fa6c10759 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 30 Mar 2018 10:20:14 -0700 Subject: 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. --- stream.c | 14 ++++++++++---- 1 file 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; -- cgit v1.2.3