patch 9.1.2104: readdirex() might be slow

Commit: 
https://github.com/vim/vim/commit/e89d97aaea0e2e94e07e24271976d0a8d2e23c38
Author: Yasuhiro Matsumoto <[email protected]>
Date:   Wed Jan 21 20:29:53 2026 +0000

    patch 9.1.2104: readdirex() might be slow
    
    Problem:  readdirex() might be slow (Mao-Yining)
    Solution: Avoid double slash in path concatenation in
              create_readdirex_item() (Yasuhiro Matsumoto)
    
    On Cygwin and MSYS2, // has a special meaning: it is treated as a prefix
    for accessing network computers.
    For example, //wsl$/ is used to access WSL.
    
    In the current Vim implementation, the directory path passed to
    readdirex() and the file name found during traversal are concatenated
    using "/".
    When the directory path already ends with /, this results in paths like:
    
      "/" + "/" + "$Recycle.Bin"
    
    which produces a //-prefixed path. Such paths are interpreted as network
    paths, so Vim ends up trying to retrieve the file size of a network
    computer named $Recycle.Bin, which is not intended.
    
    From a correctness perspective on Windows, file size retrieval should be
    skipped for paths of the following forms:
    
     //host
     //host/share
    
    However, as a first step, we should avoid generating // paths caused by
    redundant / concatenation in the first place.
    
    This change addresses this by preventing unnecessary / insertion when
    constructing paths.
    
    fixes:  #19188
    closes: #19241
    
    Signed-off-by: Yasuhiro Matsumoto <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/fileio.c b/src/fileio.c
index feb538655..e637ab397 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4822,7 +4822,7 @@ create_readdirex_item(char_u *path, char_u *name)
 {
     dict_T     *item;
     char       *p;
-    size_t     len;
+    size_t     pathlen, len;
     stat_T     st;
     int                ret, link = FALSE;
     varnumber_T        size;
@@ -4836,11 +4836,15 @@ create_readdirex_item(char_u *path, char_u *name)
        return NULL;
     item->dv_refcount++;
 
-    len = STRLEN(path) + 1 + STRLEN(name) + 1;
+    pathlen = STRLEN(path);
+    len = pathlen + 1 + STRLEN(name) + 1;
     p = alloc(len);
     if (p == NULL)
        goto theend;
-    vim_snprintf(p, len, "%s/%s", path, name);
+    if (pathlen > 0 && path[pathlen - 1] == '/')
+       vim_snprintf(p, len, "%s%s", path, name);
+    else
+       vim_snprintf(p, len, "%s/%s", path, name);
     ret = mch_lstat(p, &st);
     if (ret >= 0 && S_ISLNK(st.st_mode))
     {
diff --git a/src/version.c b/src/version.c
index 47ae372a4..30c54f9f2 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2104,
 /**/
     2103,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1vjMca-00AFyQ-Cj%40256bit.org.

Raspunde prin e-mail lui