From 8c2775f665fd4aae603b423362cf0d4d917fc0df Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Fri, 10 May 2024 12:04:27 +1000 Subject: [PATCH 1/7] Fix tests that were failing on alpine Ensure perl exists for git blame tests, replace timing sensitive `ui_out -ignore ...` with `ui_out -until '...'` --- test/commands/edit-fifo-noscroll/script | 13 ++++++------- test/run | 6 ++++++ test/tools/git/blame-in-diff/enabled | 2 +- test/tools/git/blame-in-diff/script | 7 +++---- test/tools/git/blame-jump-message/enabled | 2 +- test/tools/git/blame-jump-message/script | 7 +++---- 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/test/commands/edit-fifo-noscroll/script b/test/commands/edit-fifo-noscroll/script index f64e1a77..3a719e6a 100644 --- a/test/commands/edit-fifo-noscroll/script +++ b/test/commands/edit-fifo-noscroll/script @@ -1,19 +1,18 @@ -ui_out -ignore 7 +ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }' exec 5>fifo -ui_out '{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }' echo '* line1' >&5 ui_out '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "underline": "default", "attributes": [] }, "contents": "*" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " line1\u000a" }]], { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }] }' -ui_out -ignore 2 +ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }' echo '* line2' >&5 ui_out '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "underline": "default", "attributes": [] }, "contents": "*" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " line1\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "* line2\u000a" }]], { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }] }' -ui_out -ignore 2 +ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }' dd if=/dev/zero bs=2049 count=1 2>/dev/null | sed s/././g >&5 -ui_out -ignore 3 +ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }' ui_in '{ "jsonrpc": "2.0", "method": "keys", "params": [ "gjxH|wc -c | tr -d \" \"" ] }' -ui_out -ignore 6 +ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }' exec 5>&- -ui_out '{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "*fifo* 3:4 " }, { "face": { "fg": "black", "bg": "yellow", "underline": "default", "attributes": [] }, "contents": "[scratch]" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " - client0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "underline": "default", "attributes": [] }] }' +ui_out -until '{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "*fifo* 3:4 " }, { "face": { "fg": "black", "bg": "yellow", "underline": "default", "attributes": [] }, "contents": "[scratch]" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " - client0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "underline": "default", "attributes": [] }] }' diff --git a/test/run b/test/run index 95f71a9e..e26aea05 100755 --- a/test/run +++ b/test/run @@ -190,6 +190,12 @@ ui_out() { skip_count=$(( skip_count - 1 )) done ;; + -until) + shift + while read -r event <&4; do + [ "$event" == "$1" ] && break + done + ;; -until-grep) shift while diff --git a/test/tools/git/blame-in-diff/enabled b/test/tools/git/blame-in-diff/enabled index a041a9b4..b5b89081 100755 --- a/test/tools/git/blame-in-diff/enabled +++ b/test/tools/git/blame-in-diff/enabled @@ -1,2 +1,2 @@ #!/bin/sh -command -v git >/dev/null +command -v git >/dev/null && command -v perl >/dev/null diff --git a/test/tools/git/blame-in-diff/script b/test/tools/git/blame-in-diff/script index e5ca34b2..6adda922 100644 --- a/test/tools/git/blame-in-diff/script +++ b/test/tools/git/blame-in-diff/script @@ -1,11 +1,10 @@ -ui_out -ignore 7 -ui_out -ignore 11 +ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }' # We've jumped to the new version of line 2. Move to the old version so we # can annotate the old file. ui_in '{ "jsonrpc": "2.0", "method": "keys", "params": [ "k:git blame" ] }' -ui_out -ignore 11 +ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }' # We should have jumped to the old version of line 2, assert on kak_selection. ui_in '{ "jsonrpc": "2.0", "method": "keys", "params": [ "x" ] }' -ui_out -ignore 5 +ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }' diff --git a/test/tools/git/blame-jump-message/enabled b/test/tools/git/blame-jump-message/enabled index a041a9b4..b5b89081 100755 --- a/test/tools/git/blame-jump-message/enabled +++ b/test/tools/git/blame-jump-message/enabled @@ -1,2 +1,2 @@ #!/bin/sh -command -v git >/dev/null +command -v git >/dev/null && command -v perl >/dev/null diff --git a/test/tools/git/blame-jump-message/script b/test/tools/git/blame-jump-message/script index 67834a40..9f6fb6e0 100644 --- a/test/tools/git/blame-jump-message/script +++ b/test/tools/git/blame-jump-message/script @@ -1,6 +1,5 @@ -while ! ui_out -until-grep draw_status | grep -v '\[fifo\]' >/dev/null; -do - : +while true; do + ui_out -until-grep draw_status | grep -v '\[fifo\]' >/dev/null && break done actual_draw_status=$(ui_out -until-grep draw_status) @@ -11,5 +10,5 @@ EOF expected_subject_json=\"$(printf '%s' "$expected_subject" | sed 's/"/\\"/g')\" expected_draw_status='{ "jsonrpc": "2.0", "method": "draw_status", "params": [[{ "face": { "fg": "black", "bg": "yellow", "underline": "default", "attributes": [] }, "contents": '"$expected_subject_json"' }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "*git* 13:2 " }, { "face": { "fg": "black", "bg": "yellow", "underline": "default", "attributes": [] }, "contents": "[scratch]" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " - client0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "underline": "default", "attributes": [] }] }' -assert_eq "$actual_draw_status" "$expected_draw_status" +assert_eq "$expected_draw_status" "$actual_draw_status" ui_out -ignore 2 From 7be22f1ec28677ca0bb30316c6893ab4436734b1 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sun, 12 May 2024 11:14:17 +1000 Subject: [PATCH 2/7] Fix tests for OpenBSD Using the diff provided by @krobelus on #5173 Close #5173 --- Makefile | 5 ++++- src/file.cc | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 38484e63..6e995139 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ LDFLAGS-os-FreeBSD = -L/usr/local/lib LIBS-os-Haiku = -lnetwork -lbe -CPPFLAGS-os-OpenBSD = -DKAK_BIN_PATH="$(bindir)/kak" -I/usr/local/include +CPPFLAGS-os-OpenBSD = -DKAK_BIN_PATH=\"$(bindir)/kak\" -I/usr/local/include LDFLAGS-os-OpenBSD = -L/usr/local/lib mandir-os-OpenBSD = $(DESTDIR)$(PREFIX)/man/man1 @@ -136,6 +136,9 @@ doc/kak.1.gz: doc/kak.1 check: test test: src/kak + if [ $(os) = OpenBSD ]; then \ + export KAKOUNE_RUNTIME=$$PWD/share/kak; \ + fi && \ cd test && ./run TAGS: tags diff --git a/src/file.cc b/src/file.cc index be298964..c505f235 100644 --- a/src/file.cc +++ b/src/file.cc @@ -666,6 +666,7 @@ String get_kak_binary_path() buffer[res] = '\0'; return buffer; #elif defined(__OpenBSD__) + (void)buffer; return KAK_BIN_PATH; #elif defined(__sun__) ssize_t res = readlink("/proc/self/path/a.out", buffer, 2048); From 0e92b3fdefddbf81a008b3678faf4bf550be215c Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sun, 12 May 2024 14:18:17 +1000 Subject: [PATCH 3/7] Fix another case where git tests were hanging --- rc/tools/git.kak | 2 +- test/run | 2 +- test/tools/git/blame-in-diff/script | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rc/tools/git.kak b/rc/tools/git.kak index ac349a97..def591d8 100644 --- a/rc/tools/git.kak +++ b/rc/tools/git.kak @@ -224,7 +224,7 @@ define-command -params 1.. \ execute-keys ^commit } catch %{ # Missing commit line, assume it is an uncommitted change. - execute-keys \A + execute-keys Gg } require-module diff try %{ diff --git a/test/run b/test/run index e26aea05..a65f5396 100755 --- a/test/run +++ b/test/run @@ -193,7 +193,7 @@ ui_out() { -until) shift while read -r event <&4; do - [ "$event" == "$1" ] && break + [ "$event" = "$1" ] && break done ;; -until-grep) diff --git a/test/tools/git/blame-in-diff/script b/test/tools/git/blame-in-diff/script index 6adda922..e22b3ec8 100644 --- a/test/tools/git/blame-in-diff/script +++ b/test/tools/git/blame-in-diff/script @@ -1,9 +1,9 @@ -ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }' +ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }' # We've jumped to the new version of line 2. Move to the old version so we # can annotate the old file. ui_in '{ "jsonrpc": "2.0", "method": "keys", "params": [ "k:git blame" ] }' -ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }' +while ui_out -until-grep '"draw_status"' | grep '\[fifo\]'; do :; done > /dev/null # We should have jumped to the old version of line 2, assert on kak_selection. ui_in '{ "jsonrpc": "2.0", "method": "keys", "params": [ "x" ] }' From 97a5d68adf48e99ac19dce21b32cecc7de9f0daa Mon Sep 17 00:00:00 2001 From: Chris Webb Date: Sun, 12 May 2024 12:11:04 +0100 Subject: [PATCH 4/7] Fix error handling when reading binary path from /proc On Linux, Hurd, Cygwin, DragonFly BSD and Solaris/Illumos, Kakoune obtains a path to its binary by reading the appropriate /proc symlink target. readlink() can fail or it can fill the entire buffer, silently truncating the path if the buffer is too small. kak_assert() is compiled out in non-debug builds so we ignore a readlink() failure, corrupt the stack by writing to buffer[-1] then return a string from the uninitialised buffer. If readlink() succeeds and the binary path is sizeof(buffer) long, we write a \0 terminator beyond its end. If it is longer, we also truncate the path. Throw a fatal error on startup in all these unlikely failure cases. --- src/file.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/file.cc b/src/file.cc index c505f235..b9d3212c 100644 --- a/src/file.cc +++ b/src/file.cc @@ -634,7 +634,8 @@ String get_kak_binary_path() char buffer[2048]; #if defined(__linux__) or defined(__CYGWIN__) or defined(__gnu_hurd__) ssize_t res = readlink("/proc/self/exe", buffer, 2048); - kak_assert(res != -1); + if (res == -1 || res >= 2048) + throw runtime_error("unable to get the executable path"); buffer[res] = '\0'; return buffer; #elif defined(__FreeBSD__) or defined(__NetBSD__) @@ -662,7 +663,8 @@ String get_kak_binary_path() return path.Path(); #elif defined(__DragonFly__) ssize_t res = readlink("/proc/curproc/file", buffer, 2048); - kak_assert(res != -1); + if (res == -1 || res >= 2048) + throw runtime_error("unable to get the executable path"); buffer[res] = '\0'; return buffer; #elif defined(__OpenBSD__) @@ -670,7 +672,8 @@ String get_kak_binary_path() return KAK_BIN_PATH; #elif defined(__sun__) ssize_t res = readlink("/proc/self/path/a.out", buffer, 2048); - kak_assert(res != -1); + if (res == -1 || res >= 2048) + throw runtime_error("unable to get the executable path"); buffer[res] = '\0'; return buffer; #else From 4e5631daf3a62bff1d7c4d2e697535ed4ebffcba Mon Sep 17 00:00:00 2001 From: Chris Webb Date: Sun, 12 May 2024 12:12:58 +0100 Subject: [PATCH 5/7] Handle binary path detection errors on non-/proc platforms On FreeBSD and NetBSD, sysctl() can return -1 when the path is too long, leaving the buffer unitialised. On macOS, both _NSGetExecutablePath() and realpath() can fail with pathological paths or if memory is exhausted. On Haiku, the kak_assert(status == B_OK) check will be compiled out in non-debug builds. Detect all of these cases and error out, reshaping get_kak_binary_path() to avoid multiple repetitions of the same fatal error message. --- src/file.cc | 50 +++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/src/file.cc b/src/file.cc index b9d3212c..ca2d2834 100644 --- a/src/file.cc +++ b/src/file.cc @@ -634,10 +634,10 @@ String get_kak_binary_path() char buffer[2048]; #if defined(__linux__) or defined(__CYGWIN__) or defined(__gnu_hurd__) ssize_t res = readlink("/proc/self/exe", buffer, 2048); - if (res == -1 || res >= 2048) - throw runtime_error("unable to get the executable path"); - buffer[res] = '\0'; - return buffer; + if (res != -1 && res < 2048) { + buffer[res] = '\0'; + return buffer; + } #elif defined(__FreeBSD__) or defined(__NetBSD__) #if defined(__FreeBSD__) int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; @@ -645,40 +645,44 @@ String get_kak_binary_path() int mib[] = {CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME}; #endif size_t res = sizeof(buffer); - sysctl(mib, 4, buffer, &res, NULL, 0); - return buffer; + if (sysctl(mib, 4, buffer, &res, NULL, 0) != -1) + return buffer; #elif defined(__APPLE__) uint32_t bufsize = 2048; - _NSGetExecutablePath(buffer, &bufsize); - char* canonical_path = realpath(buffer, nullptr); - String path = canonical_path; - free(canonical_path); - return path; + char* canonical_path = NULL; + if (_NSGetExecutablePath(buffer, &bufsize) != -1) + canonical_path = realpath(buffer, nullptr); + if (canonical_path) { + String path = canonical_path; + free(canonical_path); + return path; + } #elif defined(__HAIKU__) BApplication app("application/x-vnd.kakoune"); app_info info; - status_t status = app.GetAppInfo(&info); - kak_assert(status == B_OK); - BPath path(&info.ref); - return path.Path(); + if (app.GetAppInfo(&info) == B_OK) { + BPath path(&info.ref); + return path.Path(); + } #elif defined(__DragonFly__) ssize_t res = readlink("/proc/curproc/file", buffer, 2048); - if (res == -1 || res >= 2048) - throw runtime_error("unable to get the executable path"); - buffer[res] = '\0'; - return buffer; + if (res != -1 && res < 2048) { + buffer[res] = '\0'; + return buffer; + } #elif defined(__OpenBSD__) (void)buffer; return KAK_BIN_PATH; #elif defined(__sun__) ssize_t res = readlink("/proc/self/path/a.out", buffer, 2048); - if (res == -1 || res >= 2048) - throw runtime_error("unable to get the executable path"); - buffer[res] = '\0'; - return buffer; + if (res != -1 && res < 2048) { + buffer[res] = '\0'; + return buffer; + } #else # error "finding executable path is not implemented on this platform" #endif + throw runtime_error("unable to get the executable path"); } } From 7a90473267f7f2fd8df5ae933c7b287c31ce3c97 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Fri, 17 May 2024 10:39:32 +0200 Subject: [PATCH 6/7] Revert "Make TerminalUI::get_next_key() helpers static" On macOS, backspace reportedly no longer works after and fg. The value of m_original_termios.c_cc[VERASE] seems to be wrong in a static lambda that captures a singleton "this". Not sure what's the problem. I thought that it is guaranteed that "static auto convert = [this]() { ... }" is initialized lazily, hence it should capture the correct address. Maybe the address changes somehow or it's UB / a compiler bug. This reverts commit ad36585b7ad236bea7d1c02b0679ae371c3c2a9e Closes #5155 --- src/terminal_ui.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/terminal_ui.cc b/src/terminal_ui.cc index 3ad95e40..52a25e26 100644 --- a/src/terminal_ui.cc +++ b/src/terminal_ui.cc @@ -702,7 +702,7 @@ Optional TerminalUI::get_next_key() static constexpr auto control = [](char c) { return c & 037; }; - static auto convert = [this](Codepoint c) -> Codepoint { + auto convert = [this](Codepoint c) -> Codepoint { if (c == control('m') or c == control('j')) return Key::Return; if (c == control('i')) @@ -717,7 +717,7 @@ Optional TerminalUI::get_next_key() return Key::Escape; return c; }; - static auto parse_key = [](unsigned char c) -> Key { + auto parse_key = [&convert](unsigned char c) -> Key { if (Codepoint cp = convert(c); cp > 255) return Key{cp}; // Special case: you can type NUL with Ctrl-2 or Ctrl-Shift-2 or @@ -756,7 +756,7 @@ Optional TerminalUI::get_next_key() return mod; }; - auto parse_csi = [this]() -> Optional { + auto parse_csi = [this, &convert]() -> Optional { auto next_char = [] { return get_char().value_or((unsigned char)0xff); }; int params[16][4] = {}; auto c = next_char(); From 1bd50261c8c1c867f76e79f626dc571981f15bfd Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sat, 18 May 2024 14:40:21 +1000 Subject: [PATCH 7/7] Kakoune 2024.05.18 --- doc/pages/changelog.asciidoc | 4 ++++ src/main.cc | 3 +++ 2 files changed, 7 insertions(+) diff --git a/doc/pages/changelog.asciidoc b/doc/pages/changelog.asciidoc index 4b0857ff..ee5e374f 100644 --- a/doc/pages/changelog.asciidoc +++ b/doc/pages/changelog.asciidoc @@ -3,6 +3,10 @@ This changelog contains major and/or breaking changes to Kakoune between released versions. +== Kakoune 2024.05.18 + +* Fixed tests on Alpine Linux and *BSD + == Kakoune 2024.05.09 * `flag-lines -after` switch to display text after the line diff --git a/src/main.cc b/src/main.cc index e0044db0..5b316eaa 100644 --- a/src/main.cc +++ b/src/main.cc @@ -45,6 +45,9 @@ struct { unsigned int version; StringView notes; } constexpr version_notes[] = { { + 20240518, + "» Fix tests failing on some platforms\n" + }, { 20240509, "» {+u}flag-lines -after{} highlighter\n" "» asynchronous {+u}shell-script-candidates{} completion\n"