diff options
| author | Eli Zaretskii | 2022-11-22 20:22:41 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2022-11-22 20:22:41 +0200 |
| commit | 368d2531bec84c2e75b2fd2f32bb59fc2e7ee520 (patch) | |
| tree | df31e2d30bd5aa7aa06e9ce5838750f2ee3dcbce | |
| parent | fa567684fa276511ea981cd208f99b67c521d8aa (diff) | |
| download | emacs-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.el | 16 | ||||
| -rw-r--r-- | 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." | |||
| 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 | |||
| 108 | A typical tree-sitter parser needs 10 times as much memory as the | ||
| 109 | buffer it parses. Also, the tree-sitter library has a hard limit | ||
| 110 | of 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) | |||
| 840 | static void | 840 | static void |
| 841 | treesit_check_buffer_size (struct buffer *buffer) | 841 | treesit_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 | ||
| 850 | static Lisp_Object treesit_make_ranges (const TSRange *, uint32_t, struct buffer *); | 850 | static Lisp_Object treesit_make_ranges (const TSRange *, uint32_t, struct buffer *); |