fortrangoingonforty/fortsh / 396f69c

Browse files

fix completion buffer overflow on large directories, add grep filter

The 2KB ls_output buffer overflowed on directories with many files
(like /tmp with 11KB of entries), causing completion to miss files
late in the sorted listing. Increased to 16KB and added grep -i prefix
filter when a pattern exists to limit output size.

Fixes filename and case-preserving completion on macOS /tmp.
Authored by espadonne
SHA
396f69c00954b8ad8c23975514acbf8986877827
Parents
d110363
Tree
0fa9ecc

1 changed file

StatusFile+-
M src/io/readline.f90 8 2
src/io/readline.f90modified
@@ -3470,7 +3470,7 @@ contains
34703470
 
34713471
     character(len=1024) :: ls_command, expanded_dir  ! Large enough for command
34723472
     character(len=:), allocatable :: ls_output_alloc  ! From execute_and_capture
3473
-    character(len=2048) :: ls_output  ! 2KB buffer - large enough for ls but safe for stack
3473
+    character(len=16384) :: ls_output  ! 16KB buffer for large directories
34743474
     character(len=MAX_LINE_LEN), allocatable :: entries(:)  ! Now allocatable to avoid stack overflow
34753475
     character(len=MAX_LINE_LEN) :: full_path
34763476
     character(len=:), allocatable :: home_dir, debug_mode
@@ -3508,8 +3508,14 @@ contains
35083508
 
35093509
     ! Use ls command with -F flag to mark directories with / (avoids calling test -d for each file)
35103510
     ! Trailing / on directory forces ls to list contents (not the symlink itself on macOS)
3511
+    ! When pattern is non-empty, filter with grep to avoid buffer overflow on large directories
35113512
     ! Use tr to convert newlines to spaces for easier parsing
3512
-    ls_command = 'ls -1aF "' // trim(expanded_dir) // '/" 2>/dev/null | tr ' // "'" // char(92) // 'n' // "' ' '"
3513
+    if (pattern_len > 0) then
3514
+      ls_command = 'ls -1aF "' // trim(expanded_dir) // '/" 2>/dev/null | grep -i "^' // &
3515
+        trim(pattern) // '" | tr ' // "'" // char(92) // 'n' // "' ' '"
3516
+    else
3517
+      ls_command = 'ls -1aF "' // trim(expanded_dir) // '/" 2>/dev/null | tr ' // "'" // char(92) // 'n' // "' ' '"
3518
+    end if
35133519
 
35143520
     ! Debug output
35153521
     if (debug_enabled) then