From 61fd8c4003b361503160424cbed1960153f40290 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 27 May 2025 12:10:14 +0530 Subject: [PATCH] Fix #8682 --- docs/changelog.rst | 2 ++ kitty/screen.c | 6 ++++-- kitty_tests/screen.py | 6 ++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index a299a3147..d738f08b0 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -117,6 +117,8 @@ Detailed list of changes - hints kitten: Preserve line breaks when the hint is over a line break (:iss:`8674`) +- Fix a segfault when using the :ac:`copy_ansi_to_clipboard` action (:iss:`8682`) + 0.42.1 [2025-05-17] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/screen.c b/kitty/screen.c index a677a93dd..565380758 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -3644,10 +3644,11 @@ ansi_for_range(Screen *self, const Selection *sel, bool insert_newlines, bool st s.output_buf->active_hyperlink_id = 0; s.output_buf->len = 0; RAII_PyObject(ans, PyTuple_New(y_limit - min_y + 1)); RAII_PyObject(nl, PyUnicode_FromString("\n")); - if (!ans || !nl) return NULL; + RAII_PyObject(empty_string, PyUnicode_FromString("")); + if (!ans || !nl || !empty_string) return NULL; bool has_escape_codes = false; bool need_newline = false; - for (int i = 0, y = min_y; y < y_limit; y++, i++) { + for (int i = 0, y = min_y; y < y_limit && i < PyTuple_GET_SIZE(ans) - 1; y++, i++) { const bool is_first_line = y == min_y; s.output_buf->len = 0; Line *line = range_line_(self, y); @@ -3666,6 +3667,7 @@ ansi_for_range(Screen *self, const Selection *sel, bool insert_newlines, bool st if (x_limit <= x_start && (is_only_whitespace_line || line_is_empty(line))) { // we want a newline on only whitespace lines even if they are continued if (insert_newlines) need_newline = true; + PyTuple_SET_ITEM(ans, i, Py_NewRef(need_newline ? nl : empty_string)); } else { char_type prefix_char = need_newline ? '\n' : 0; while (x_start < x_limit) { diff --git a/kitty_tests/screen.py b/kitty_tests/screen.py index 7ed190937..dc3b84f98 100644 --- a/kitty_tests/screen.py +++ b/kitty_tests/screen.py @@ -677,6 +677,12 @@ def ts(*args): self.ae(s.text_for_selection(True), ('a\x1b[32mb\x1b[39mc ', 'xy', '\x1b[m')) self.ae(s.text_for_selection(True, True), ('a\x1b[32mb\x1b[39mc', 'xy', '\x1b[m')) # ]]]]]]]]]]]]]]]]]]]] + s.reset() + s.draw('a'), s.carriage_return(), s.linefeed(), s.linefeed(), s.draw('b') + s.start_selection(0, 0) + s.update_selection(4, 4) + self.ae(''.join(s.text_for_selection()), 'a\n\nb') + self.ae(''.join(s.text_for_selection(True)), 'a\n\nb') def test_soft_hyphen(self): s = self.create_screen()