Max Nikulin writes: >> Many times I need to create and share a public link to a file >> in my local folder. In the Nextcloud forum I learned how it can be done >> from the command line using curl, > .. >> │ (result-raw (shell-command-to-string >> │ (concat "curl -u " >> │ "\"" >> │ my-username >> │ ":" >> │ my-passwd >> │ "\"" > > Juan Manuel, your function is a nice proof of concept, but posting > such code you are responsible for users who may try to use it verbatim > having less experience with elisp. > > Use at least `shell-quote-argument' (though it docstring has a link to > info "(elisp)Security Considerations"). Just adding quote characters > is unsafe. You may avoid non-alphanumeric characters in passwords and > file names for good reasons, but for other users a quote character may > dramatically change the executed command. > > When TRAMP support is not necessary, arguments should be passed to > external binary as a list without intermediate shell command. I know, > Emacs does not have a convenience function with such calling > convention similar to `shell-command-to-string'. > > I am almost sure that Emacs has a package to send HTTP POST requests > directly from elisp. Unsure it has convenient enough API (reasonable > default timeouts, etc.), but it should be safer for working with > peculiar file names and passwords stuffed with characters having > special meaning in shell. I admit that the code would be more verbose. > It may save you time for recovering you system from damage caused by > unexpected interpretation of a shell command.
Maxim, you are right that the use of shell-quote-argument is preferable in cases like these to avoid unexpected problems with filenames, passwords, and so on. I try to use it almost always. If I don't use it more often, it's either because I'm lazy (because of my way of naming the files, I don't expect this type of problems) or because I think it's unnecessary, although not 100% free of danger[1], as in this case. I'm not saying my behavior is exemplary, I'm just saying what I tend to do. I should probably always use shell-quote-argument. In this case, the affected part of my function would perhaps look better like this: (shell-command-to-string (mapconcat #'shell-quote-argument `("curl" "-u" ,(format "%s:%s" my-user my-password) "-H" "OCS-APIRequest:true" "-X" "POST" ,(format "%s/ocs/v1.php/apps/files_sharing/api/v1/shares" nextcloud-url) "-d" ,(format "path=%s/%s" nextcloud-public-folder-name file) "-d" "shareType=3" "-d" "permissions=1") " ")) [1] I think that a problem in this context would not go beyond the fact that the function simply did not work as expected. Perhaps it would have been better to use call-process-shell-command, instead of shell-command-to-string, and extract the resulting string from the output buffer. On the other hand, I agree with you that whenever possible it is better to use an Elisp solution than a shell command. Best regards, Juan Manuel -- -- ------------------------------------------------------ Juan Manuel Macías https://juanmanuelmacias.com https://lunotipia.juanmanuelmacias.com https://gnutas.juanmanuelmacias.com