Re: Feature Request: Custom delimeter for single quotes

2019-11-01 Thread Ilkka Virta

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

2019-11-01 Thread Patrick Blesi
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

2019-11-01 Thread Eli Schwartz
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



signature.asc
Description: OpenPGP digital signature


Re: Feature Request: Custom delimeter for single quotes

2019-11-01 Thread Andreas Schwab
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."



Running 32 bit program on 64 bit system makes bash etc. look bad

2019-11-01 Thread 積丹尼 Dan Jacobson
$ mapping/taipower/pole2tm
bash: mapping/taipower/pole2tm: No such file or directory

Must be a bash bug! Proof:
$ ls -l mapping/taipower/pole2tm
-rwxr-xr-x 1 jidanni jidanni 11290 2012-06-19  mapping/taipower/pole2tm

But wait,
$ strace mapping/taipower/pole2tm
execve("mapping/taipower/pole2tm", ["mapping/taipower/pole2tm"], 0x7ffd53416200 
/* 58 vars */) = -1 ENOENT (No such file or directory)
strace: exec: No such file or directory
+++ exited with 1 +++

Must also be a strace bug...

Ah,
$ file mapping/taipower/pole2tm
mapping/taipower/pole2tm: ELF 32-bit LSB executable...

but we are running it on
$ arch
x86_64

Anyway, perhaps somebody could submit a kernel bug, telling them to
somehow make bash, etc. look less bad, by a clearer error message, as I
suppose bash cannot always catch such cases, to make a better error
message.

In fact maybe bash could catch it (expensive?):

First "stat" the file.
If it doesn't exist bash should make its own message
bash: /tmp/abce: No such file or directory
If it does, then bash should be prepared to catch the kernel's message
(which is referring to a *different* file, which yes, actually does not exist.)
Whereupon bash could make a better error message.