aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/view.c
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2024-09-28 00:30:09 +0200
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2024-09-28 05:02:34 +0200
commit5395a7da901e4af9758762215b75d943ef253ef3 (patch)
treedcc0f2298e1e0d6a118b6b63347d3bd5baa596b7 /src/view.c
parent973e50d1f43b680863551f1aea30d88616488e84 (diff)
downloadsciteco-5395a7da901e4af9758762215b75d943ef253ef3.tar.gz
check the memory limit and allow interruptions when loading files
* Previously you could open files of arbitrary size and the limit would be checked only afterwards. * Many, but not all, cases should now be detected earlier. Since Scintilla allocates lots of memory as part of rendering, you can still run into memory limits even after successfully loading the file. * Loading extremely large files can also be potentially slow. Therefore, it is now possible to interrupt via CTRL+C. Again, if the UI is blocking because of stuff done as part of rendering, you still may not be able to interrupt the "blocking" operation.
Diffstat (limited to 'src/view.c')
-rw-r--r--src/view.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/src/view.c b/src/view.c
index 0d1d168..b70d9cd 100644
--- a/src/view.c
+++ b/src/view.c
@@ -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;
}
/**