Re: %q with truncating size loses safeness of %q

2020-04-18 Thread Sam Liddicott
In my case I was using process substitution to generate a dynamic bashrc
file as part of invoking an SDK environment.

Naturally those lines which emit environment variable assignments use %q

I had one build version tracking variable which was to be limited to 7
characters and set to a lowercase form of the username.

The most concise but surprisingly unsafe form is.

printf 'BUILD_VER_SUFFIX=%.7q\n' "${USER,,}"

That's clearly not artificially contrived; (though the user has the ability
to directly mess up their build environment anyway if they so wish).

The answer is obviously "don't do that" but it that requires a special
obscure knowledge which isn't documented.

Can we have bash printf to also not do that? Or if it must break the
security feature got which it exists can at least be documented?

I think I've made myself clear so I went harp on about it anymore unless I
find a more egregious opportunity for abuse.

Sam


On Fri, 17 Apr 2020, 23:38 Robert Elz,  wrote:

> Date:Fri, 17 Apr 2020 16:12:20 -0400
> From:Chet Ramey 
> Message-ID:  <4bacf2f0-9802-67d3-f30b-80e37d058...@case.edu>
>
>   | I would say this is a programmer error.  The way precisions work with
>   | string arguments is that the argument is fetched or generated (this
>   | includes generating the quoted string for %q or the expanded string for
>   | %b) and then printf writes number of bytes (!) from that generated
> string
>   | specified by the precision.
>
> This happens only because of the cheap way we (and I presume you)
> implement things - in any rational scheme, it would take the precision
> chars from the source string, and then quote them.
>
> But that's hard - instead we just use printf to do the work, %q quotes
> the arg string, and then the 'q' is changed to a 's' in the format, and
> we just call printf(3) to do the work (padding, justification, ...)
>
> The only excuse for this is pragmatics, no-one would deliberately set
> out to design something quite that bogus.
>
> The end result is as Greg said, "Don't do that", if precisions are
> needed with %q do something like
>
> printf 'echo %q%q\n' "$(printf %.2s "a'b")" ';ls'
>
> which produces
>
> echo a\'\;ls
>
> which I expect is the desired result.
>
> kre
>
>


Re: [bug] PROMPT_COMMAND is not executed as expected in some situations

2020-04-18 Thread Franklin, Jason
On 4/16/20 10:11 AM, Chet Ramey wrote:
> On 4/16/20 9:21 AM, Franklin, Jason wrote:
>> On 4/15/20 5:35 PM, Chet Ramey wrote:
>>> These all pretty much all fall into the category of the editor reprinting
>>> the prompt before it returns.
>>
>> Hmmm...
>>
>> So, is there no way to have Bash handle the printing of the prompt after
>> the return of the command and of the editor?
> 
> Bash doesn't have control at that point. It's readline running a bindable
> function. It's as if you hit ^L when the readline line buffer was empty:
> readline reprints the prompt, but should it call back to bash somehow --
> through a hook function that doesn't currently exist -- to execute
> PROMPT_COMMAND?
> 
>> This would allow PROMPT_COMMAND to function as expected.  It is
>> surprising to see status indicators in my prompt NOT be updated when
>> using .
> 
> I don't think that most people expect PROMPT_COMMAND in that situation.
>> I thought that this would be easy.  Is it really not possible to fix?
> 
> I'm saying it's not a bug at all, and doesn't need fixing.

As a programmer, I can understand that this may be a tough fix.
However, as a user, I must say that I expect PROMPT_COMMAND to be run
whenever PS1 is printed to prompt me for a new command.  The bash man
page makes this clear. To quote:

PROMPT_COMMAND
  If set, the value is executed as a command prior to issuing each
  primary prompt.

My PROMPT_COMMAND does a lot of neat stuff.  It works flawlessly too,
but obviously not after using, for example, , because it
doesn't get invoked then.  This means that indicators about the most
recent command are not updated when I open an editor to enter a command
(or use histverify or show completions).

A simple example where the prompt is not updated as expected (this one
doesn't involve PROMPT_COMMAND, but shows why a full prompt update is
desired):

$ bash --norc
$ PS1='[$?] '"$PS1"
# now, exit status is in prompt, which is pretty useful
# use  to edit and enter command "false" and save and quit
# the exit status should be [1], but is [0], so the indicator is wrong

I hope this clarifies my point of view on this issue.  It may be a tough
ask, so I don't expect a ton of effort to fix this if others aren't
complaining.

In any case, thanks so much for all of your magnificent work on Bash.
I've been using Bash for years, and I don't plan to stop!  I wish I had
the knowledge of Bash internals to just code up a patch.  I tried, but
it was to no avail. :(

Thanks!

-- 
Jason Franklin



Re: looking for consistent C-c trap behavior

2020-04-18 Thread Chet Ramey
On 4/17/20 3:59 PM, gentoo_eshoes--- via Bug reports for the GNU Bourne
Again SHell wrote:
> I've noticed that if I trap SIGINT in a bash script, the behavior when 
> encountering C-c depends on whether an external command (eg. 'sleep 100') or 
> a builtin command (like 'read -p') was encountered.

It's only `read', and it happens when bash is executing in default mode.
Here's what I wrote (off-list) earlier this month about it; it has come
up several times before:

=
The idea is that trapping the signal doesn't interrupt the read, kind of
like a read system call getting restarted if interrupted by a signal and
reading from the terminal. Since the read doesn't get interrupted, you have
to satisfy it by entering newline. If you didn't have the trap on INT it
would interrupt the read.

Bash has behaved this way in its default mode for just about forever. In
posix mode, it interrupts the read system call.
=

The behavior of running the trap action and restarting the read if it
returns is still there in default mode for backwards compatibility.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: [PATCH] Exit status by no-argument `return' for function calls in trap handlers

2020-04-18 Thread Chet Ramey
On 4/16/20 1:21 PM, Koichi Murase wrote:

> Bash Version: 5.0
> Patch Level: 11
> Release Status: release
> 
> Summary:
> 
>   The behavior of no-argument `return' in trap handlers has been
>   changed from Bash 4.4 to follow the description of POSIX.  Recently
>   this behavior caused problems in my Bash script.  I am wondering
>   whether this change actually matches with the behavior meant by
>   POSIX because the change introduces unreasonable constraints in
>   writing shell functions.
> 
>   For the condition of this special treatment of `return', POSIX says
>   ``When return is executed in a trap action''.  Here are two possible
>   interpretation: (A) `return's specified in the argument string of
>   `trap' builtin are affected, or (B) all the `return's in entire
>   runtime function-call tree in trap processing are affected.  I guess
>   that POSIX wanted to provide a way to exit functions that received
>   signals without changing the value of `$?'.  If that is the case,
>   the POSIX should have meant (A).  However, the current Bash
>   implementation behaves as if it follows the interpretation (B).

The POSIX wording seems straightforward and implies (B). The `action'
is a string that is defined to behave as if it were the argument to
`eval', so it can be an arbitrary command, which makes (A) unlikely.

You could always ask the austin-group list for an interpretation, or
send me something that I could forward to the list for you.


>   If all the `return's in the entire function-call tree are affected
>   in trap processing as in the interpretation (B), one cannot reliably
>   use no-argument `return' to return the last-command exit status.  To
>   avoid the problem, one has to always write the exit status
>   explicitly as `return $?', and there is no use case for no-argument
>   `return' at all. 

That's an unreasonable statement, throwing out all uses of return without
an argument because of how it behaves while running a trap.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: looking for consistent C-c trap behavior

2020-04-18 Thread gentoo_eshoes--- via Bug reports for the GNU Bourne Again SHell




Apr 18, 2020, 22:03 by chet.ra...@case.edu:

> On 4/17/20 3:59 PM, gentoo_eshoes--- via Bug reports for the GNU Bourne
> Again SHell wrote:
>
>> I've noticed that if I trap SIGINT in a bash script, the behavior when 
>> encountering C-c depends on whether an external command (eg. 'sleep 100') or 
>> a builtin command (like 'read -p') was encountered.
>>
>
> It's only `read', and it happens when bash is executing in default mode.
>
That's pretty cool that's only 'read', I wrongly assumed(without any prior 
testing) that that applies to any builtin. I still haven't tested, I trust you.

> Here's what I wrote (off-list) earlier this month about it; it has come
> up several times before:
>
> =
> The idea is that trapping the signal doesn't interrupt the read, kind of
> like a read system call getting restarted if interrupted by a signal and
> reading from the terminal. Since the read doesn't get interrupted, you have
> to satisfy it by entering newline. If you didn't have the trap on INT it
> would interrupt the read.
>
> Bash has behaved this way in its default mode for just about forever. In
> posix mode, it interrupts the read system call.
>
can confirm that indeed `bash --posix` does interrupt the 'read -p' on first 
C-c, however, the inside-trap seen exit code is 0, but if the trap doesn't 
`exit` itself, then the exit code after the 'read -p' is seen correctly as 130, 
ie.
$ ./sigintread.bash 
Press C-c here...^Cinterrupted sees exit code '0'

Normal exit sees ec=130

Would it be possible to somehow get 130 even inside the trap function?

this would then be equivalent with interrupting 'sleep' for example:
$ ./sigintread.bash 
^Cinterrupted sees exit code '130'

Normal exit sees ec=130


On another note, I naively tried to patch out the POSIX requirement, for my 
own/local_use puposes but had no effect:
in this code
+  /* posix mode SIGINT during read -e. We only get here if SIGINT is trapped. 
*/
+  if (posixly_correct && this_shell_builtin == read_builtin && sig == 2)
+    {
+  last_command_exit_value = 128|SIGINT;
+  throw_to_top_level ();
+    }
by removing "posixly_correct &&" from above. I've no idea why that would have 
no effect, a bit stumped.I've even tried with a prior 'make clean'. The only 
explanation is that some other code that happens only during `POSIXly correct` 
mode is affecting this somehow...




Re: looking for consistent C-c trap behavior

2020-04-18 Thread gentoo_eshoes--- via Bug reports for the GNU Bourne Again SHell




Apr 18, 2020, 23:41 by gentoo_esh...@tutanota.com:

>
> On another note, I naively tried to patch out the POSIX requirement, for my 
> own/local_use puposes but had no effect:
> in this code
> +  /* posix mode SIGINT during read -e. We only get here if SIGINT is 
> trapped. */
> +  if (posixly_correct && this_shell_builtin == read_builtin && sig == 2)
> +    {
> +  last_command_exit_value = 128|SIGINT;
> +  throw_to_top_level ();
> +    }
> by removing "posixly_correct &&" from above. I've no idea why that would have 
> no effect, a bit stumped.
> I've even tried with a prior 'make clean'. The only explanation is that some 
> other code that happens only during `POSIXly correct` mode is affecting this 
> somehow...
>
regarding the above, I stand corrected: it does indeed have effect but only on 
'read -e' (just as the comment states), that bash_event_hook() function isn't 
entered for 'read -p' which to me was surprising, yet no doubt correct(I'm 
guessing).
The code that allows 'read -p' to be interrupted when posixly_correct, must 
then be somewhere else, I shall keep lookin', yet I fear I might not find it :-"




Re: [PATCH] Exit status by no-argument `return' for function calls in trap handlers

2020-04-18 Thread Koichi Murase
2020-04-19 5:12 Chet Ramey :
> The POSIX wording seems straightforward and implies (B). The `action'
> is a string that is defined to behave as if it were the argument to
> `eval', so it can be an arbitrary command, which makes (A) unlikely.
>
> You could always ask the austin-group list for an interpretation, or
> send me something that I could forward to the list for you.

Thank you for the suggestion.  Is  the
mailing list you mentioned above?  I have created an account in
opengroup.org and subscribed to the mailing list.  I will later write a
question on wording of `return' special builtin in that list.

> That's an unreasonable statement, throwing out all uses of return without
> an argument because of how it behaves while running a trap.

OK.  I agree that for the shell functions that will not be used in
trap handlers, no-argument `return' can be used without problems.

Actually the situation in my script (ble.sh) is a little bit special.
In my script, some parts of Bash features are emulated.  I run `eval
-- "$PROMPT_COMMAND"' in SIGWINCH handler where `PROMPT_COMMAND' is
specified by users so is not under the control of the script but under
the control of the user.  Naively, with interpretation (B), I need to put
restrictions on the commands that can be specified in
`PROMPT_COMMAND', on which there are no restrictions in the original
Bash.  The use of no-argument `return' is common, and such
restrictions are non-trivial for users.  In fact, there are already
existing Bash configurations, that use no-argument `return' in
`PROMPT_COMMAND', which I would like to support with my script.  One
example is `bash-preexec' (https://github.com/rcaloras/bash-preexec)
which aims to provide a feature like `preexec' and `precmd' hooks of
zsh.  `bash-preexec' uses no-argument `return'.  The configuration
provided by iTerm2 for shell--terminal integration also uses this
`bash-preexec' framework.

I would appreciate it if you could provide me some suggestion on other
ways to work around the general problems caused by such user-provided
`PROMPT_COMMAND'?

2020-04-17 2:21 Koichi Murase :
>   Also, I have checked the behavior of other shells. `zsh', `ash'
>   family (dash/ash, busybox sh) and `posh' does not implement the
>   special treatment of `return' in trap handlers.  `ksh' family
>   (ksh93, mksh) and `yash' implements the interpretation (B).  There
>   is no existing implementation of (A).  But currently I still think
>   the intepretation (A) is reasonable.  If there is rationale for the
>   interpretation (B), I would like to know it.

Let me correct this paragraph. Actually `zsh', `dash' and `busybox'
implement the behavior of the interpretation (A).  After my previous
email, I noticed that there was an oversight in testing the shells.
With the attached script `0015-test4.sh',

$ bash 0015-test4.sh
In trap-argument: last command preceding the trap action
In a function call: last command preceding the trap action
$ bash-4.3 0015-test4.sh
In trap-argument: last command in the trap action
In a function call: last command in the trap action
$ zsh 0015-test4.sh
In trap-argument: last command preceding the trap action
In a function call: last command in the trap action
$ dash 0015-test4.sh
In trap-argument: last command preceding the trap action
In a function call: last command in the trap action
$ busybox sh 0015-test4.sh
In trap-argument: last command preceding the trap action
In a function call: last command in the trap action
$ mksh 0015-test4.sh
In trap-argument: last command preceding the trap action
In a function call: last command preceding the trap action
$ ksh 0015-test4.sh
In trap-argument: last command preceding the trap action
In a function call: last command preceding the trap action
$ yash 0015-test4.sh
In trap-argument: (failed to exit the function)
In a function call: last command preceding the trap action
$ posh 0015-test4.sh
In trap-argument: last command in the trap action
In a function call: last command in the trap action

which can be summarized in the following list:

Interpretation (A): zsh, dash, busybox
Interpretation (B): bash-5.0, ksh, mksh
Interpretation (B) [broken?]: yash
Not implemented: bash-4.3, posh

--
Koichi
#!/bin/bash

setexit() { return "$1"; }
invoke() { kill -USR1 $$; return 222; }

trap 'setexit 111; return' USR1
invoke
case $? in
(0)   echo 'In trap-argument: last command preceding the trap action' ;;
(111) echo 'In trap-argument: last command in the trap action' ;;
(222) echo 'In trap-argument: (failed to exit the function)' ;;
(*)   echo 'In trap-argument: (unexpected)' ;;
esac

stat=99
handler() { setexit 111; return; }
trap 'handler; stat=$?; return' USR1
invoke
case $stat in
(0)   echo 'In a function call: last command preceding the trap action' ;;
(111) echo 'In a function call: last command in the trap action' ;;
(*)   echo 'In a function call: (unexpected)' ;;
esac