aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2025-02-15 13:15:36 +0200
committerEli Zaretskii2025-02-15 13:15:36 +0200
commit0f768b8843bcdbbfa1c64aeee64d2de7d62c0d13 (patch)
tree169e8c187e3df855363bf1e5ddaa4cff7b4c07c3
parentc37e7cef42877e8222872ee6e00ecd8ab833d56b (diff)
downloademacs-0f768b8843bcdbbfa1c64aeee64d2de7d62c0d13.tar.gz
emacs-0f768b8843bcdbbfa1c64aeee64d2de7d62c0d13.zip
Prevent buffer overflow in line-numbering code
* src/xdisp.c (maybe_produce_line_number): Limit the value of 'display-line-numbers-width' to what can be shown in the window, and set dimension of the lnum_buf[] accordingly. (Bug#75969)
-rw-r--r--src/xdisp.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index c9bcafe57fd..0de5aee86dd 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -25008,7 +25008,6 @@ maybe_produce_line_number (struct it *it)
25008 25008
25009 /* Produce the glyphs for the line number. */ 25009 /* Produce the glyphs for the line number. */
25010 struct it tem_it; 25010 struct it tem_it;
25011 char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1];
25012 bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE; 25011 bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE;
25013 ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */ 25012 ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */
25014 int lnum_face_id = merge_faces (it->w, Qline_number, 0, DEFAULT_FACE_ID); 25013 int lnum_face_id = merge_faces (it->w, Qline_number, 0, DEFAULT_FACE_ID);
@@ -25037,7 +25036,17 @@ maybe_produce_line_number (struct it *it)
25037 if (!it->lnum_width) 25036 if (!it->lnum_width)
25038 { 25037 {
25039 if (FIXNATP (Vdisplay_line_numbers_width)) 25038 if (FIXNATP (Vdisplay_line_numbers_width))
25040 it->lnum_width = XFIXNAT (Vdisplay_line_numbers_width); 25039 {
25040 EMACS_INT lnum_width = XFIXNAT (Vdisplay_line_numbers_width);
25041 /* Limit the width to show at least 1 text character. */
25042 int lnum_width_limit
25043 = (it->last_visible_x - it->first_visible_x)
25044 / FRAME_COLUMN_WIDTH (it->f)
25045 - 5 /* leave space for a few characters */
25046 - 2; /* two spaces around the number */
25047 it->lnum_width
25048 = clip_to_bounds (1, lnum_width, lnum_width_limit);
25049 }
25041 25050
25042 /* Max line number to be displayed cannot be more than the one 25051 /* Max line number to be displayed cannot be more than the one
25043 corresponding to the last row of the desired matrix. */ 25052 corresponding to the last row of the desired matrix. */
@@ -25057,6 +25066,8 @@ maybe_produce_line_number (struct it *it)
25057 it->lnum_width = max (it->lnum_width, log10 (max_lnum) + 1); 25066 it->lnum_width = max (it->lnum_width, log10 (max_lnum) + 1);
25058 eassert (it->lnum_width > 0); 25067 eassert (it->lnum_width > 0);
25059 } 25068 }
25069 /* Extra +2 for the two blanks we add before and after the number. */
25070 char *lnum_buf = alloca (it->lnum_width + 2 + 1);
25060 if (EQ (Vdisplay_line_numbers, Qrelative)) 25071 if (EQ (Vdisplay_line_numbers, Qrelative))
25061 lnum_offset = it->pt_lnum; 25072 lnum_offset = it->pt_lnum;
25062 else if (EQ (Vdisplay_line_numbers, Qvisual)) 25073 else if (EQ (Vdisplay_line_numbers, Qvisual))