diff options
-rw-r--r-- | src/view.c | 28 | ||||
-rw-r--r-- | tests/testsuite.at | 5 |
2 files changed, 28 insertions, 5 deletions
@@ -45,6 +45,7 @@ #include "error.h" #include "qreg.h" #include "eol.h" +#include "memory.h" #include "view.h" /** @memberof teco_view_t */ @@ -216,8 +217,11 @@ teco_view_load_from_channel(teco_view_t *ctx, GIOChannel *channel, GError **erro */ struct stat stat_buf = {.st_size = 0}; if (!fstat(g_io_channel_unix_get_fd(channel), &stat_buf) && - stat_buf.st_size > 0) + stat_buf.st_size > 0) { + if (!teco_memory_check(stat_buf.st_size, error)) + goto error; teco_view_ssm(ctx, SCI_ALLOCATE, stat_buf.st_size, 0); + } g_auto(teco_eol_reader_t) reader; teco_eol_reader_init_gio(&reader, channel); @@ -230,14 +234,24 @@ teco_view_load_from_channel(teco_view_t *ctx, GIOChannel *channel, GError **erro teco_string_t str; GIOStatus rc = teco_eol_reader_convert(&reader, &str.data, &str.len, error); - if (rc == G_IO_STATUS_ERROR) { - teco_view_ssm(ctx, SCI_ENDUNDOACTION, 0, 0); - return FALSE; - } + if (rc == G_IO_STATUS_ERROR) + goto error; if (rc == G_IO_STATUS_EOF) break; teco_view_ssm(ctx, SCI_APPENDTEXT, str.len, (sptr_t)str.data); + + /* + * Even if we checked initially, knowing the file size, + * Scintilla could allocate much more bytes. + */ + if (!teco_memory_check(0, error)) + goto error; + + if (G_UNLIKELY(teco_interface_is_interrupted())) { + teco_error_interrupted_set(error); + goto error; + } } /* @@ -259,6 +273,10 @@ teco_view_load_from_channel(teco_view_t *ctx, GIOChannel *channel, GError **erro teco_view_ssm(ctx, SCI_ENDUNDOACTION, 0, 0); return TRUE; + +error: + teco_view_ssm(ctx, SCI_ENDUNDOACTION, 0, 0); + return FALSE; } /** diff --git a/tests/testsuite.at b/tests/testsuite.at index 8a3ba96..fc7de4f 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -160,6 +160,11 @@ AT_SETUP([Memory limiting during spawning]) AT_CHECK([$SCITECO -e "50*1000*1000,2EJ 0,128ED @EC'dd if=/dev/zero'"], 1, ignore, ignore) AT_CLEANUP +AT_SETUP([Memory limiting during file reading]) +AT_CHECK([dd if=/dev/zero of=big-file.txt bs=1000 count=50000], 0, ignore, ignore) +AT_CHECK([$SCITECO -8e "50*1000*1000,2EJ @EB'big-file.txt'"], 1, ignore, ignore) +AT_CLEANUP + AT_SETUP([Q-Register stack cleanup]) AT_CHECK([$SCITECO -e '@<:@a'], 0, ignore, ignore) AT_CLEANUP |