From 368d2531bec84c2e75b2fd2f32bb59fc2e7ee520 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 22 Nov 2022 20:22:41 +0200 Subject: [PATCH] Fix 'treesit-max-buffer-size' and its use * lisp/treesit.el (treesit-max-buffer-size): Avoid overflow in computing buffer-size limit. Account for 32-but systems built "--with-wide-int". Extend doc string. (treesit-ready-p): Compare the limit with the size of the buffer in bytes, not in characters. * src/treesit.c (treesit_check_buffer_size): Measure buffer size in bytes. --- lisp/treesit.el | 16 +++++++++++----- src/treesit.c | 6 +++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lisp/treesit.el b/lisp/treesit.el index 10c6b093222..75e859f13f7 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -98,10 +98,16 @@ indent, imenu, etc." (defcustom treesit-max-buffer-size (let ((mb (* 1024 1024))) ;; 40MB for 64-bit systems, 15 for 32-bit. - (if (> most-positive-fixnum (* 4 1024 mb)) - (* 40 mb) - (* 15 mb))) - "Maximum buffer size for enabling tree-sitter parsing (in bytes)." + (if (or (< most-positive-fixnum (* 2.0 1024 mb)) + ;; 32-bit system with wide ints. + (string-match-p "--with-wide-int" system-configuration-options)) + (* 15 mb) + (* 40 mb))) + "Maximum buffer size (in bytes) for enabling tree-sitter parsing. + +A typical tree-sitter parser needs 10 times as much memory as the +buffer it parses. Also, the tree-sitter library has a hard limit +of max unsigned 32-bit value for byte offsets into buffer text." :type 'integer :version "29.1") @@ -1583,7 +1589,7 @@ instead of emitting a warning." (when (not (treesit-available-p)) (setq msg "tree-sitter library is not compiled with Emacs") (throw 'term nil)) - (when (> (buffer-size) treesit-max-buffer-size) + (when (> (position-bytes (1- (point-max))) treesit-max-buffer-size) (setq msg "buffer larger than `treesit-max-buffer-size'") (throw 'term nil)) (dolist (lang language-list) diff --git a/src/treesit.c b/src/treesit.c index 835b07c9312..4a7c4019561 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -840,11 +840,11 @@ treesit_ensure_position_synced (Lisp_Object parser) static void treesit_check_buffer_size (struct buffer *buffer) { - ptrdiff_t buffer_size = (BUF_Z (buffer) - BUF_BEG (buffer)); - if (buffer_size > UINT32_MAX) + ptrdiff_t buffer_size_bytes = (BUF_Z_BYTE (buffer) - BUF_BEG_BYTE (buffer)); + if (buffer_size_bytes > UINT32_MAX) xsignal2 (Qtreesit_buffer_too_large, build_pure_c_string ("Buffer size cannot be larger than 4GB"), - make_fixnum (buffer_size)); + make_fixnum (buffer_size_bytes)); } static Lisp_Object treesit_make_ranges (const TSRange *, uint32_t, struct buffer *); -- 2.39.5