ref: 0d97b5826534055fd224c61178b483c9c37f2c99
parent: f7bc61e874ebde2e29dad4075ab3834d78998df6
author: Jakub Kądziołka <kuba@kadziolka.net>
date: Wed Jul 3 11:37:17 EDT 2019
Avoid potentially implementation-defined behavior when using a pipe as input
--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -156,13 +156,32 @@
if (pBuffer == NULL)
fatalerror("%s: Out of memory!", __func__);
- size_t size = 0, capacity;
+ size_t size = 0, capacity = -1;
char *buf = NULL;
- fseek(f, 0, SEEK_END);
- capacity = ftell(f);
- rewind(f);
+ /*
+ * Check if we can get the file size without implementation-defined
+ * behavior:
+ *
+ * From ftell(3p):
+ * [On error], ftell() and ftello() shall return −1, and set errno to
+ * indicate the error.
+ *
+ * The ftell() and ftello() functions shall fail if: [...]
+ * ESPIPE The file descriptor underlying stream is associated with a
+ * pipe, FIFO, or socket.
+ *
+ * From fseek(3p):
+ * The behavior of fseek() on devices which are incapable of seeking
+ * is implementation-defined.
+ */
+ if (ftell(f) != -1) {
+ fseek(f, 0, SEEK_END);
+ capacity = ftell(f);
+ rewind(f);
+ }
+ // If ftell errored or the block above wasn't executed
if (capacity == -1)
capacity = 4096;