From 02eefdd52c7d1a8f5ac896c22d5ff6aff065bf72 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 9 Sep 2024 15:28:03 -0400 Subject: [PATCH] Fix issues with path reading from pipes (don't UTF8 validate chunks, because they can be fragments) and some misc buffering issues. --- builtins/path.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/builtins/path.c b/builtins/path.c index e63e4e4..1dde5aa 100644 --- a/builtins/path.c +++ b/builtins/path.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "array.h" @@ -257,24 +258,35 @@ public Text_t Path$read(Path_t path) close(fd); return Text$from_strn(gc_mem, (size_t)sb.st_size); } else { - const size_t chunk_size = 256; - char *buf = GC_MALLOC_ATOMIC(chunk_size); - Text_t contents = Text(""); - ssize_t just_read; - do { - just_read = read(fd, buf, chunk_size); + size_t capacity = 256, len = 0; + char *content = GC_MALLOC_ATOMIC(capacity); + for (;;) { + char chunk[256]; + ssize_t just_read = read(fd, chunk, sizeof(chunk)); if (just_read < 0) fail("Failed while reading file: %k (%s)", &path, strerror(errno)); - else if (just_read == 0) + else if (just_read == 0) { + if (errno == EAGAIN || errno == EINTR) + continue; break; + } - if (u8_check((uint8_t*)buf, (size_t)just_read) != NULL) - fail("File does not contain valid UTF8 data!"); - contents = Texts(contents, Text$from_strn(buf, (size_t)just_read)); - buf = GC_MALLOC_ATOMIC(chunk_size); - } while (just_read > 0); + if (len + (size_t)just_read >= capacity) { + content = GC_REALLOC(content, (capacity *= 2)); + } + + memcpy(&content[len], chunk, (size_t)just_read); + len += (size_t)just_read; + + if ((size_t)just_read < sizeof(chunk)) + break; + } close(fd); - return contents; + + if (u8_check((uint8_t*)content, len) != NULL) + fail("File does not contain valid UTF8 data!"); + + return Text$from_strn(content, len); } }