[openssh-commits] [openssh] 03/04: upstream: When tab-completing a filename, ensure that the completed
git+noreply at mindrot.org
git+noreply at mindrot.org
Thu Oct 9 10:09:08 AEDT 2025
This is an automated email from the git hooks/post-receive script.
djm pushed a commit to branch master
in repository openssh.
commit 0f3b8fd68a29766697d7a709bae8b0a61da6cff2
Author: djm at openbsd.org <djm at openbsd.org>
AuthorDate: Wed Oct 8 21:48:40 2025 +0000
upstream: When tab-completing a filename, ensure that the completed
string does not end up mid-way through a multibyte character, as this will
cause a fatal() later on.
based on GHPR#587 from @TaoistBrickscarrier; feedback tb@ kevlo@
ok dtucker@
OpenBSD-Commit-ID: efb977164b4e20d61204a66201a7592ba8291362
---
sftp.c | 52 ++++++++++++++++++++++++++++++++++------------------
1 file changed, 34 insertions(+), 18 deletions(-)
diff --git a/sftp.c b/sftp.c
index 3b505eea2..57516a73a 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp.c,v 1.245 2025/10/02 04:23:11 djm Exp $ */
+/* $OpenBSD: sftp.c,v 1.246 2025/10/08 21:48:40 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm at openbsd.org>
*
@@ -1863,29 +1863,44 @@ complete_display(char **list, u_int len)
static char *
complete_ambiguous(const char *word, char **list, size_t count)
{
+ size_t i, j, matchlen;
+ char *tmp;
+ int len;
+
if (word == NULL)
return NULL;
- if (count > 0) {
- u_int y, matchlen = strlen(list[0]);
+ if (count == 0)
+ return xstrdup(word); /* no options to complete */
- /* Find length of common stem */
- for (y = 1; list[y]; y++) {
- u_int x;
+ /* Find length of common stem across list */
+ matchlen = strlen(list[0]);
+ for (i = 1; i < count && list[i] != NULL; i++) {
+ for (j = 0; j < matchlen; j++)
+ if (list[0][j] != list[i][j])
+ break;
+ matchlen = j;
+ }
- for (x = 0; x < matchlen; x++)
- if (list[0][x] != list[y][x])
- break;
+ /*
+ * Now check that the common stem doesn't finish in the middle of
+ * a multibyte character.
+ */
+ mblen(NULL, 0);
+ for (i = 0; i < matchlen;) {
+ len = mblen(list[0] + i, matchlen - i);
+ if (len <= 0 || i + (size_t)len > matchlen)
+ break;
+ i += (size_t)len;
+ }
+ /* If so, truncate */
+ if (i < matchlen)
+ matchlen = i;
- matchlen = x;
- }
-
- if (matchlen > strlen(word)) {
- char *tmp = xstrdup(list[0]);
-
- tmp[matchlen] = '\0';
- return tmp;
- }
+ if (matchlen > strlen(word)) {
+ tmp = xstrdup(list[0]);
+ tmp[matchlen] = '\0';
+ return tmp;
}
return xstrdup(word);
@@ -2065,6 +2080,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
tmp2 = tmp + filelen - cesc;
len = strlen(tmp2);
/* quote argument on way out */
+ mblen(NULL, 0);
for (i = 0; i < len; i += clen) {
if ((clen = mblen(tmp2 + i, len - i)) < 0 ||
(size_t)clen > sizeof(ins) - 2)
--
To stop receiving notification emails like this one, please contact
djm at mindrot.org.
More information about the openssh-commits
mailing list