Closed aarondill closed 5 months ago
The recent changes in the suda.vim
plugin involve restructuring the command execution functions. The suda#system
function has been split into suda#systemlist
and a new suda#system
function for different output handling. Command construction within these functions has been updated, along with adjustments to input and output processing in related functions.
File(s) | Summary |
---|---|
autoload/suda.vim |
Refactored suda#system to suda#systemlist , introduced new suda#system , updated command construction, adjusted input/output processing. |
🐇✨
Among lines of code, a rabbit did play,
Refactoring functions to light the way.
With a tweak here and a split there,
Commands now flow with a newfound flair.
"In the realm of Vim," the rabbit did say,
"May your plugins shine, in the light of day!"
🌟🐰
autoload/suda.vim (4)
`7-14`: Consider revising the handling of `suda#executable` to support a list of executables for better flexibility and clarity, as discussed in the TODO comments. --- `36-69`: > :memo: **NOTE** > This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [20-55] Ensure that the handling of password input and command execution in `suda#systemlist` adheres to security best practices, particularly in avoiding potential exposure of sensitive information.Verification successful
--- The handling of password input and command execution in `suda#systemlist` adheres to security best practices. The password is securely collected using `inputsecret` and the command construction in `s:get_command` does not expose sensitive information. The use of `--` to separate sudo options from the command further ensures that parameters are treated securely.--- `86-100`: > :memo: **NOTE** > This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [78-97] Evaluate the feasibility of using `readfile()` in `suda#read` for performance improvement and simplification, as suggested in the TODO comment. Would you like me to help implement this change or should I open a GitHub issue to track this task? --- `143-154`: > :memo: **NOTE** > This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [130-151] Consider using `writefile()` in `suda#write` to enhance performance and reduce complexity, as suggested in the TODO comment. Would you like me to help implement this change or should I open a GitHub issue to track this task?Scripts Executed
The following scripts were executed for the analysis: --- Script: ```shell #!/bin/bash # Verify that password handling is secure and does not expose sensitive information in logs or error messages. rg --type vimscript 'inputsecret' --context 5 ``` Length of output: 479 --- --- Script: ```shell #!/bin/bash # Check the implementation of s:get_command to ensure it handles passwords securely rg --type vimscript 'function! s:get_command' --context 10 ``` Length of output: 1064
@lambdalisue what do you think about this?
Sorry for late. Well, probably we should add suda#systemlist
function and use it internally.
So you're saying have both suda#system
and suda#systemlist
? I was thinking about this, but went with the current approach to reduce code duplication. since the two functions do nearly the same thing, except calling system
and systemlist
respectively.
if you think it would increase clarity, I could implement separate functions as wrappers around the current suda#system
implementation.
if you think it would increase clarity, I could implement separate functions as wrappers around the current suda#system implementation.
Yes please. We may remove suda#system
later but not now 👍
@lambdalisue to be clear, I was thinking about the following simple implementation
" name tbd
function s:_system(cmd, list, ...)
... " the current implementation
endfunction
function suda#system(cmd, ...)
return s:_system(cmd, 0, ...)
endfunction
function suda#systemlist(cmd, ...)
return s:_system(cmd, 1, ...)
endfunction
is something like this acceptable?
I'm sorry. I meant something like
" arguments must like systemlist()
function! suda#systemlist(cmd, ...) abort
" ...
endfunction
" arguments must like sysmte()
function! suda#system(cmd, ...) abort
" ...
return suda#systemlist(...)
endfunction
So that we can simply remove suda#system
later.
that wouldn't work the way you're thinking.
suda#system
mimics the vim system
function.
system
and systemlist
have the same arguments (cmd
as a string or list, and input
as optional string/list/buffer id)
they differ in return types. system
returns a string representing the command's output, while systemlist
returns a list representing the command's output (split by newlines, preserving nulls as embedded newlines)
this is why I went the approach that i did, the input arguments are the same, but the return type varies depending on if it calls system
or systemlist
Apologies. I completely forgot that I had previously made the exact same mistake a long time ago. Nevertheless, in this scenario, could we consider the following approach?
function! suda#systemlist(cmd, ...) abort
" ...
endfunction
function! suda#system(cmd, ...) abort
let result = call('suda#systemlist', [a:cmd] + a:000)
return join(result, "\n")
endfunction
Alternatively, if you find suda#system()
to be too redundant, we can omit it and perhaps introduce suda#systemlist()
as part of a new major release.
@lambdalisue This aproach also fails because the output of systemlist
translates NULs into NLs. If we only had to spawn the process once, we could have a helper which returns the argument list, but we spawn the process once, check for failure and potentially spawn it again, meaning we would have to pass in a funcref anyways.
I don't see a good way to implement it without passing a funcref to system
/systemlist
to a helper, reimplementing system
's processing of the output (which is already provided by VimScript :pensive:), or a lot of code duplication.
systemlist({expr} [, {input}]) systemlist()
Same as system(), but returns a List with lines (parts of output separated by NL) with NULs transformed into NLs. Output is the same as readfile() will output with {binary} argument set to "b", except that there is no extra empty item when the result ends in a NL. Note that on MS-Windows you may get trailing CR characters.
@aarondill Well, nvm for NULs while Vim's system()
doesn't support anyway. Using join(systemlist(...), "\n")
should be enough I think.
@lambdalisue that approach won't work unless we remove the NULs before joining (since they're represented by newlines).
it seems that the default system
turns NULs into \u0001 so they don't break strings. should we do this too, or just remove them from the string?
it seems that the default system turns NULs into \u0001 so they don't break strings. should we do this too, or just remove them from the string?
Let's follow Vim's behavior 👍
@lambdalisue I've implemented this change in a583f3a7e764daee6f119887c879f8b048fc80fa
LGTM
This eliminates the need for shell-escaping, and removes possibility of accidental shell-injection.
This is technically a breaking change, since suda#system is globally exposed; however this is not a documented public api, so the chance of breakage is minimal.
Note that this *changes the behavior of g:suda#executeable! It is no longer shell-processed, but rather treated as a path/name to an executable and processed by the os in that way. Should we split suda#executable on spaces to preserve the old behavior? Should we allow suda#executable to (optionally) be a list to allow passing arguments?
Summary by CodeRabbit
suda
functionality for improved performance and flexibility.