aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2022-11-22 20:22:41 +0200
committerEli Zaretskii2022-11-22 20:22:41 +0200
commit368d2531bec84c2e75b2fd2f32bb59fc2e7ee520 (patch)
treedf31e2d30bd5aa7aa06e9ce5838750f2ee3dcbce
parentfa567684fa276511ea981cd208f99b67c521d8aa (diff)
downloademacs-368d2531bec84c2e75b2fd2f32bb59fc2e7ee520.tar.gz
emacs-368d2531bec84c2e75b2fd2f32bb59fc2e7ee520.zip
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.
-rw-r--r--lisp/treesit.el16
-rw-r--r--src/treesit.c6
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."
98(defcustom treesit-max-buffer-size 98(defcustom treesit-max-buffer-size
99 (let ((mb (* 1024 1024))) 99 (let ((mb (* 1024 1024)))
100 ;; 40MB for 64-bit systems, 15 for 32-bit. 100 ;; 40MB for 64-bit systems, 15 for 32-bit.
101 (if (> most-positive-fixnum (* 4 1024 mb)) 101 (if (or (< most-positive-fixnum (* 2.0 1024 mb))
102 (* 40 mb) 102 ;; 32-bit system with wide ints.
103 (* 15 mb))) 103 (string-match-p "--with-wide-int" system-configuration-options))
104 "Maximum buffer size for enabling tree-sitter parsing (in bytes)." 104 (* 15 mb)
105 (* 40 mb)))
106 "Maximum buffer size (in bytes) for enabling tree-sitter parsing.
107
108A typical tree-sitter parser needs 10 times as much memory as the
109buffer it parses. Also, the tree-sitter library has a hard limit
110of max unsigned 32-bit value for byte offsets into buffer text."
105 :type 'integer 111 :type 'integer
106 :version "29.1") 112 :version "29.1")
107 113
@@ -1583,7 +1589,7 @@ instead of emitting a warning."
1583 (when (not (treesit-available-p)) 1589 (when (not (treesit-available-p))
1584 (setq msg "tree-sitter library is not compiled with Emacs") 1590 (setq msg "tree-sitter library is not compiled with Emacs")
1585 (throw 'term nil)) 1591 (throw 'term nil))
1586 (when (> (buffer-size) treesit-max-buffer-size) 1592 (when (> (position-bytes (1- (point-max))) treesit-max-buffer-size)
1587 (setq msg "buffer larger than `treesit-max-buffer-size'") 1593 (setq msg "buffer larger than `treesit-max-buffer-size'")
1588 (throw 'term nil)) 1594 (throw 'term nil))
1589 (dolist (lang language-list) 1595 (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)
840static void 840static void
841treesit_check_buffer_size (struct buffer *buffer) 841treesit_check_buffer_size (struct buffer *buffer)
842{ 842{
843 ptrdiff_t buffer_size = (BUF_Z (buffer) - BUF_BEG (buffer)); 843 ptrdiff_t buffer_size_bytes = (BUF_Z_BYTE (buffer) - BUF_BEG_BYTE (buffer));
844 if (buffer_size > UINT32_MAX) 844 if (buffer_size_bytes > UINT32_MAX)
845 xsignal2 (Qtreesit_buffer_too_large, 845 xsignal2 (Qtreesit_buffer_too_large,
846 build_pure_c_string ("Buffer size cannot be larger than 4GB"), 846 build_pure_c_string ("Buffer size cannot be larger than 4GB"),
847 make_fixnum (buffer_size)); 847 make_fixnum (buffer_size_bytes));
848} 848}
849 849
850static Lisp_Object treesit_make_ranges (const TSRange *, uint32_t, struct buffer *); 850static Lisp_Object treesit_make_ranges (const TSRange *, uint32_t, struct buffer *);