Re: Feature Request: Custom delimeter for single quotes
I just came across: Example 19-8 Here: http://tldp.org/LDP/abs/html/here-docs.html It looks like this example meets my needs. I'm curious why this method is referred to as devious though? -- Patrick On Thu, Oct 31, 2019 at 11:54 PM Patrick Blesi wrote: > I'm looking for a hybrid between single quotes and a here doc or here > string. > > The main use case is for accepting arbitrary user-specified text. I would > like to wrap this text in single quotes so as to prevent any variable > expansion or interpretation of the text of any kind. Additionally, I would > like to allow the users to include single quotes in their text without > requiring that they escape these quotes. > > Something akin to the following would alleviate the need to communicate > that users must escape single quotes, but also provide the same literal > string behavior of single quotes. > > presuming the arbitrarily substituted text is: > > echo 'this command is specified by the user' > > Then a syntax for this single quote heredoc behavior could be like: > > $ sh -c <<^MAGIC_WORD echo 'this command is specified by the user' > MAGIC_WORD > > Everything within the MAGIC_WORD declarations would not have command > substitution, variable expansion, etc, but would be treated as if it were > wrapped in single quotes with the exception that single quotes between the > MAGIC_WORDs need not be escaped. > > Pardon my naïveté, does any such feature exist or are there good ways to > accomplish this? If not, is this something that could feasibly be > implemented? Would it be desirable? > > Thanks, > > Patrick >
Feature Request: Custom delimeter for single quotes
I'm looking for a hybrid between single quotes and a here doc or here string. The main use case is for accepting arbitrary user-specified text. I would like to wrap this text in single quotes so as to prevent any variable expansion or interpretation of the text of any kind. Additionally, I would like to allow the users to include single quotes in their text without requiring that they escape these quotes. Something akin to the following would alleviate the need to communicate that users must escape single quotes, but also provide the same literal string behavior of single quotes. presuming the arbitrarily substituted text is: echo 'this command is specified by the user' Then a syntax for this single quote heredoc behavior could be like: $ sh -c <<^MAGIC_WORD echo 'this command is specified by the user' MAGIC_WORD Everything within the MAGIC_WORD declarations would not have command substitution, variable expansion, etc, but would be treated as if it were wrapped in single quotes with the exception that single quotes between the MAGIC_WORDs need not be escaped. Pardon my naïveté, does any such feature exist or are there good ways to accomplish this? If not, is this something that could feasibly be implemented? Would it be desirable? Thanks, Patrick
Re: Feature Request: Custom delimeter for single quotes
The actual use case is taking a command from a Ruby script: https://github.com/braintree/runbook/blob/4a0f0770a8a2a7be135cf13ee435d981b5975a06/lib/runbook/helpers/tmux_helper.rb#L23 `tmux send-keys -t #{target} #{_pager_escape_sequence} '#{command}' C-m` The user specifies the command they want to run as a Ruby string and it gets interpolated into the above string and then executed (The backticks in Ruby invoke the command in a subprocess and return the output as a string, #{} is string interpolation). As you can see, if the user-specified command has a single quote, it will break this command unless escaped. I think doing something like this should serve my needs: ` command=$(cat <<'MAGIC_WORD' #{command} MAGIC_WORD ) tmux send-keys -t #{target} #{_pager_escape_sequence} "$command" C-m ` So that no single quote escaping is required. The non-valid input for the command would be MAGIC_WORD. Do you know if this command is POSIX compliant/supported by a large number of shells? Is is supported by the bourne shell? On Fri, Nov 1, 2019 at 3:37 AM Ilkka Virta wrote: > On 1.11. 06:54, Patrick Blesi wrote: > > I'm looking for a hybrid between single quotes and a here doc or here > > string. > > > > The main use case is for accepting arbitrary user-specified text. > > Do your users enter the text by directly editing the script? > Would it make more sense to use e.g. 'read' to read the input directly > from the user? > > input="" > nl=' > ' > echo "Enter text, end with ^D:" > while IFS= read -r line; do > input="$input$line$nl" > done > > printf "You entered:\n---\n%s---\n" "$input" > > > or to just have the text in a separate file (not the script) and read it > from there? > > input=$(< inputfile) > > > That way, the text appears in a variable, and you don't need to care > about quotes inside it. > > > (You could also read from stdin with just input=$(cat) instead of the > while read loop but that feels a bit odd to me for some reason.) > > > I would > > like to wrap this text in single quotes so as to prevent any variable > > expansion or interpretation of the text of any kind. Additionally, I > would > > like to allow the users to include single quotes in their text without > > requiring that they escape these quotes. > > > > Something akin to the following would alleviate the need to communicate > > that users must escape single quotes, but also provide the same literal > > string behavior of single quotes. > > > > presuming the arbitrarily substituted text is: > > > > echo 'this command is specified by the user' > > > > Then a syntax for this single quote heredoc behavior could be like: > > > > $ sh -c <<^MAGIC_WORD echo 'this command is specified by the user' > > MAGIC_WORD > > > > Everything within the MAGIC_WORD declarations would not have command > > substitution, variable expansion, etc, but would be treated as if it were > > wrapped in single quotes with the exception that single quotes between > the > > MAGIC_WORDs need not be escaped. > > > > Pardon my naïveté, does any such feature exist or are there good ways to > > accomplish this? If not, is this something that could feasibly be > > implemented? Would it be desirable? > > > > Thanks, > > > > Patrick > > > > > -- > Ilkka Virta / itvi...@iki.fi >
Re: Feature Request: Custom delimeter for single quotes
Upon further inspection, what Andreas pointed out is actually what I need. Just to close the loop on everything... It looks like Ruby does support execution with and without a shell: https://apidock.com/ruby/Kernel/system. The reasoning for using two programming languages is that sometimes it is easier to accomplish things in Ruby and sometimes it is easier to accomplish things in a shell. Providing the user the option to implement something via shell or via Ruby allows for maximum flexibility and utility. Regarding, posix compliance, I was specifically asking about whether the following code could be expected to be supported by any POSIX-compliant shell: command=$(cat <<'MAGIC_WORD' #{command} MAGIC_WORD ) tmux send-keys -t %1 q C-u "$command" C-m Not sure if this is the canonical POSIX shell reference: https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_07_04, but it appears that the quoted here-doc and command substitution are shell features defined by the POSIX standard. Thank you very much for your help. -- Patrick On Fri, Nov 1, 2019 at 3:44 PM Eli Schwartz wrote: > On 11/1/19 3:57 PM, Patrick Blesi wrote: > > The actual use case is taking a command from a Ruby script: > > > > > https://github.com/braintree/runbook/blob/4a0f0770a8a2a7be135cf13ee435d981b5975a06/lib/runbook/helpers/tmux_helper.rb#L23 > > > > `tmux send-keys -t #{target} #{_pager_escape_sequence} '#{command}' C-m` > > > > The user specifies the command they want to run as a Ruby string and it > > gets interpolated into the above string and then executed (The backticks > in > > Ruby invoke the command in a subprocess and return the output as a > string, > > #{} is string interpolation). As you can see, if the user-specified > command > > has a single quote, it will break this command unless escaped. > > I don't know about ruby. > > I know that in, say, python, the subprocess module can take an array > with a command executable and its arguments, and execute it using the > exec() family of functions. > > You can optionally request that the subprocess module do its execution > via a shell, just like system() does, but it's generally not exactly > recommended. > > Have you considered rewriting your ruby program to not use vulnerable > methods of executing subprocesses? Given that ruby is, presumably, a > powerful programming language, I don't understand why you would want to > write a program that now uses *two* programming languages: > > - ruby > - /bin/sh > > when you could do all your work in ruby. > > If you absolutely require using shell syntax in your subprocess for > inexplicable reasons, you can use the shell syntax embedded within this > pseudocode, which would be executed using the exec() family of functions: > > {'sh', '-c', 'do_things "$1"', '_', 'argv_containing_user_input'} > > given sh is being passed an argument without introducing a shell, and > that argument is assigned to the shell variable $1, that argument can be > defined and passed to exec() containing anything which ruby wants to put > there. > > Safely. > > > I think doing something like this should serve my needs: > > > > ` > > command=$(cat <<'MAGIC_WORD' > > #{command} > > MAGIC_WORD > > ) > > tmux send-keys -t #{target} #{_pager_escape_sequence} "$command" C-m > > ` > > So that no single quote escaping is required. The non-valid input for the > > command would be MAGIC_WORD. Do you know if this command is POSIX > > compliant/supported by a large number of shells? Is is supported by the > > bourne shell? > > Is what command POSIX compliant? > > - The one you're proposing be added, right now, to bash and bash alone? > - tmux? > - cat with quoted delimiter tokens? > > -- > Eli Schwartz > Arch Linux Bug Wrangler and Trusted User > >
Re: Feature Request: Custom delimeter for single quotes
I was originally thinking I did not want to shell-quote these because I may have wanted part of the user input to be interpreted by the shell. Thinking more about this, I want the entirety of user input to be treated as a verbatim string to be passed to the tmux command, so this is exactly what I want. Regarding security issues, that isn't a concern for this use case because the user is allowed to execute arbitrary commands within the application. The application is invoked at the command line as opposed to through a web or other restricted interface. Any security concerns would be implemented at the OS level (file permissions, etc.). Thank you for your help. -- Patrick On Fri, Nov 1, 2019 at 3:57 PM Andreas Schwab wrote: > On Nov 01 2019, Patrick Blesi wrote: > > > The actual use case is taking a command from a Ruby script: > > > > > https://github.com/braintree/runbook/blob/4a0f0770a8a2a7be135cf13ee435d981b5975a06/lib/runbook/helpers/tmux_helper.rb#L23 > > > > `tmux send-keys -t #{target} #{_pager_escape_sequence} '#{command}' C-m` > > > > The user specifies the command they want to run as a Ruby string and it > > gets interpolated into the above string and then executed (The backticks > in > > Ruby invoke the command in a subprocess and return the output as a > string, > > #{} is string interpolation). As you can see, if the user-specified > command > > has a single quote, it will break this command unless escaped. > > Just shell-quote the characters in the interpolated string, as you need > to do anyway for the other interpolated strings. Not doing this would > be a security bug waiting to happen. > > Andreas. > > -- > Andreas Schwab, sch...@linux-m68k.org > GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 > "And now for something completely different." >