aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/nvim/zip.lua
diff options
context:
space:
mode:
authorBarrett Ruth <62671086+barrettruth@users.noreply.github.com>2026-08-19 21:35:26 +1000
committerGitHub <noreply@github.com>2026-08-19 07:35:26 -0400
commit743bca9202e96869b102d9883c40cf778dbd0df3 (patch)
tree056b9be7865a4979d25ec19547e4a8f018a4fefd /runtime/lua/nvim/zip.lua
parent0a414a7fbb833597e8dc627ba64459001fc61a85 (diff)
downloadrneovim-743bca9202e96869b102d9883c40cf778dbd0df3.tar.gz
rneovim-743bca9202e96869b102d9883c40cf778dbd0df3.tar.bz2
rneovim-743bca9202e96869b102d9883c40cf778dbd0df3.zip
fix(zip): lost password if sent before unzip disables echo #41377
Diffstat (limited to 'runtime/lua/nvim/zip.lua')
-rw-r--r--runtime/lua/nvim/zip.lua30
1 files changed, 22 insertions, 8 deletions
diff --git a/runtime/lua/nvim/zip.lua b/runtime/lua/nvim/zip.lua
index ed2ccdcfa4..e5d3d8b532 100644
--- a/runtime/lua/nvim/zip.lua
+++ b/runtime/lua/nvim/zip.lua
@@ -196,10 +196,18 @@ local function extract_with_password(command, source, path, dir)
return 'could not start unzip'
end
+ -- Info-ZIP prints the prompt before disabling echo, and disables it with TCSAFLUSH, which
+ -- drops a password sent in that window. Echo is still on there, so an echo means "resend".
+ local sent = ''
+ local function echoed()
+ return sent ~= '' and buffered:find(sent .. '\r', 1, true) ~= nil
+ end
+
local function wanted()
return exited ~= nil
or buffered:find('password: ', 1, true) ~= nil
or buffered:find('reenter: ', 1, true) ~= nil
+ or echoed()
end
local reenter = false
@@ -213,15 +221,21 @@ local function extract_with_password(command, source, path, dir)
if exited ~= nil then
break
end
- local label = reenter and 'Password incorrect, try again: '
- or ('Password for %s: '):format(path)
- local password = vim.fn.inputsecret(label)
- if password == '' then
- vim.fn.jobstop(job)
- return 'cancelled'
+ if echoed() then
+ -- Wait for its read(), else the resend is dropped too.
+ vim.wait(10)
+ else
+ local label = reenter and 'Password incorrect, try again: '
+ or ('Password for %s: '):format(path)
+ sent = vim.fn.inputsecret(label)
+ if sent == '' then
+ vim.fn.jobstop(job)
+ return 'cancelled'
+ end
+ reenter = true
end
- reenter, buffered = true, ''
- vim.fn.chansend(job, password .. '\r')
+ buffered = ''
+ vim.fn.chansend(job, sent .. '\r')
end
if exited ~= 0 then