Segmentation fault when nesting several thousand heredocs

2017-02-10 Thread Tom
  #15 0x0043abd0 in execute_connection (command=0x1f13cc8, 
asynchronous=0x0, pipe_in=0x, pipe_out=0x, 
fds_to_close=0x2dccd08) at execute_cmd.c:2592
(More stack frames follow...)

And here's a full backtrace of that stack frame it died in, in morecore():

(gdb) > bt full 1
#0  0x004e60fb in morecore (nu=0x27e9428) at malloc.c:554
mp = 0x3
nblks = 0x0
siz = 0x27e9388
sbrk_amt = 0x0
set = {
  __val = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
}
oset = {
  __val = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
}
blocked_sigs = 0x0
(More stack frames follow...)

Repeat-By:
This function will create 40k heredocs. Pipe it to bash, or redirect it to a
file and get bash to run it.

function heredoc_abuse {
num=${1:-4}
printf -- "---> stack size: %d\n" $(ulimit -s) >&2
printf -- "---> generating %d heredocs %s\n" $num >&2
for ((i=1; i<=$num; i++)); do printf "for x$i in 1; do cat << 
A\n"; done
for ((i=1; i<=$num; i++)); do printf "A\n"; done
    for ((i=1; i<=$num; i++)); do printf "done\n"; done
}

The heredocs look like this:

for x1 in 1; do cat << A
for x2 in 1; do cat << A
for x3 in 1; do cat << A
A
A
A
done
done
done


~~
Tom Shaddock
hello@apricot.pictures



macOS 14 objc `+initialize` forced crash due to fork after thread

2024-05-02 Thread Tom
eferredLanguages(forCurrentUser: 
Swift.Bool) -> Swift.Array + 76
frame #15: 0x0001844ec9c4 Foundation`@objc static 
__C.NSLocale._preferredLanguagesForCurrentUser(Swift.Bool) -> 
Swift.Array + 44
frame #16: 0x000182ece0b4 CoreFoundation`CFLocaleCopyPreferredLanguages 
+ 28
frame #17: 0x000101386174 
libintl.8.dylib`_libintl_language_preferences_default at langprefs.c:253:32 
[opt]
frame #18: 0x000101384ac8 libintl.8.dylib`libintl_dcigettext [inlined] 
guess_category_value(category=6, categoryname="LC_MESSAGES") at 
dcigettext.c:1643:26 [opt]
frame #19: 0x000101384a68 
libintl.8.dylib`libintl_dcigettext(domainname="bash", msgid1="%s: command not 
found", msgid2=0x, plural=0, n=0, category=) at 
dcigettext.c:710:19 [opt]
frame #20: 0x000101382338 
libintl.8.dylib`libintl_dcgettext(domainname=, 
msgid=, category=) at dcgettext.c:47:10 [opt] 
[artificial]
frame #21: 0x000101382350 
libintl.8.dylib`libintl_gettext(msgid=) at gettext.c:55:10 [opt] 
[artificial]
frame #22: 0x000100ddf658 
bash`execute_disk_command(words=0x629e8e70, 
redirects=0x, command_line="derp", pipe_in=, 
pipe_out=, async=, fds_to_close=0x6298c040, 
cmdflags=0) at execute_cmd.c:5731:24 [opt]
frame #23: 0x000100dda378 
bash`execute_simple_command(simple_command=, pipe_in=-1, 
pipe_out=-1, async=, fds_to_close=0x6298c040) at 
execute_cmd.c:4814:12 [opt]
frame #24: 0x000100dd8188 
bash`execute_command_internal(command=0x62b800a0, asynchronous=0, 
pipe_in=-1, pipe_out=-1, fds_to_close=0x6298c040) at 
execute_cmd.c:866:4 [opt]
frame #25: 0x000100dd74b4 bash`execute_command(command=) 
at execute_cmd.c:413:12 [opt]
frame #26: 0x000100dc62c4 bash`reader_loop at eval.c:171:8 [opt]
frame #27: 0x000100dc4c78 bash`main(argc=2, argv=, 
env=) at shell.c:833:3 [opt]
frame #28: 0x000182a6a0e0 dyld`start + 2360
```


Repeat-By:

```
#!/usr/bin/env bash

set -eu

fetch_gettext () {
  wget --continue 
https://mirror.endianness.com/gnu/gettext/gettext-0.22.5.tar.gz
}

fetch_bash () {
  wget --continue https://mirror.endianness.com/gnu/bash/bash-5.2.tar.gz
  mkdir -p bash-5.2-patches
  pushd bash-5.2-patches
  for i in $(seq -w 01 26)
  do
wget --continue 
https://mirror.endianness.com/gnu/bash/bash-5.2-patches/bash52-0${i}
  done
  popd
}

fetch () {
  mkdir -p assets
  pushd assets
  
  fetch_gettext
  
  fetch_bash
  
  popd
}

build_gettext () {
  prefix=${1}

  tar -xzf ../assets/gettext-0.22.5.tar.gz
  
  pushd gettext-0.22.5/gettext-runtime
  ./configure --prefix=${prefix} --silent
  make --jobs 12 --silent install
  popd
}

build_bash () {
  prefix=${1}

  tar -xzf ../assets/bash-5.2.tar.gz

  pushd bash-5.2
  for i in $(seq -w 01 26)
  do
patch -p0 < ../../assets/bash-5.2-patches/bash52-0${i}
  done
  
  LDFLAGS=-L${prefix}/lib ./configure --silent
  make --jobs 12 --silent
  popd
}

build () {
  prefix=$(mktemp -d)
  
  rm -rf build
  mkdir build
  pushd build

  build_gettext ${prefix}

  build_bash ${prefix}

  popd
}

fetch
build

./build/bash-5.2/bash -l  # execute invalid command
```


Regards,

Tom Sullivan

Head Developer
Most Significant Bit Software

e:  t...@msbit.com.au
p:  +61 407 890 821



Re: macOS 14 objc `+initialize` forced crash due to fork after thread

2024-05-03 Thread Tom
> Oh, I see, from gettext-0.22.

Yes, that's right, this came up in the context of a [macports bug report][1].

> Still, how should bash avoid this using only public function interfaces?

That report has a work-around invoking a syntax error which presumably calls 
out to `setlocale`/`gettext` pre-`fork`, caching the result somewhere (`bash` 
or `gettext`?) such that the offending call post-`fork` on an unknown command 
doesn't trigger this issue.

That feels brittle; a more general approach might be to move both invocations 
either side of the fork (as alluded to by the [gettext maintainer][2]), which 
for `bash` probably means calling `gettext` before `fork`.

[1]: https://trac.macports.org/ticket/68638
[2]: https://lists.gnu.org/archive/html/bug-gettext/2024-05/msg1.html



Re: macOS 14 objc `+initialize` forced crash due to fork after thread

2024-05-06 Thread Tom
> It looks like it's the call to setlocale() that creates the auxiliary
> threads, and the call to gettext() that forces the artificial crash.

Yep, that's my understanding.

> So any call to gettext() in the parent process before any fork would be
> sufficient to complete the initialization?

It does appear that way; running the following (a modification of the repro I 
put to the `gettext` list):

```
#include 
#include 
#include 

int main() {
  unsetenv("LANG");

  setlocale(LC_ALL, "");

  gettext("");

  if (fork()== 0) {
gettext("test");
  }
}
```

causes the issue to no longer trigger. Note that `LANG` needs to be cleared 
before the call to `setlocale` to trigger the issue.



Re: macOS 14 objc `+initialize` forced crash due to fork after thread

2024-05-15 Thread Tom
> Thanks. I'll add a call to gettext() that will happen right after bash sets
> its default values for the various locale categories.

When building the latest commit on `devel` 
(`b3d8c8a4e7c5417d986f93f646ea740cb13c08d7`) this issue no longer occurs.

Thanks!



Incorrect LINENO with exported nested functions with loops

2021-10-05 Thread Tom Coleman
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-redhat-linux-gnu'
-DCONF_VENDOR='redhat' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash'
-DSHELL -DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib  -D_GNU_SOURCE
-DRECYCLES_PIDS -DDEFAULT_PATH_VALUE='/usr/local/bin:/usr/bin'
 -DSYSLOG_HISTORY -O2 -g -pipe -Wall -Werror=format-security
-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions
-fstack-protector-strong -grecord-gcc-switches
-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1
-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic
-fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection
-Wno-parentheses -Wno-format-security
uname output: Linux gadi-login-06.gadi.nci.org.au
4.18.0-305.19.1.el8.nci.x86_64 #1 SMP Mon Sep 27 03:06:23 UTC 2021 x86_64
x86_64 x86_64 GNU/Linux
Machine Type: x86_64-redhat-linux-gnu

Bash Version: 4.4
Patch Level: 20
Release Status: release

Description:
If you have a function, which exports another function, and that
exported function contains a generic for loop, the LINENO variable is
incorrect for loops in future functions which contain another loop which
uses ((..)) notation.

Whilst the above system information says bash 4.4.20 20, I have
seen it in 3.2.51 and 4.2.46 too.

Repeat-By:
Below is a sample script to replicate the bug in LINENO.

The LINENO variable for the 'i' loop which is printed out by the
PS4 is incorrect when that DO_BACKUP function is exported, and the second
'j' loop is uncommented. If you instead uncomment the first 'j' loop, the
LINENO variables are correct. If DO_BACKUP does not have a loop inside it,
the LINENO variables are all correct.

#!/bin/bash
export PS4='+L$LINENO + '
setup() {
DO_BACKUP() {
  for d in 1 2 3; do
break
  done
}
export -f DO_BACKUP
}
run() {
for i in 1; do
#for j in 1; do  # Uncomment this 'j' loop instead of the next and
LINENO is correct
#for ((j=1; j<=2; j++)); do  # Uncomment this 'j' loop and LINENO
is incorrect
true
done
done
}
set -x
setup
run



Example output with first 'j' loop uncommented:

$ bash run.sh
+L20 + setup
+L9 + export -f DO_BACKUP
+L21 + run
+L12 + for i in 1
+L13 + for j in 1
+L15 + true

Example output with the second 'j' loop uncommented:

$ bash run.sh
+L20 + setup
+L9 + export -f DO_BACKUP
+L21 + run
+L5 + for i in 1
+L14 + (( j=1 ))
+L14 + (( j<=1 ))
+L15 + true
+L14 + (( j++ ))
+L14 + (( j<=1 ))


Regards,
Tom Coleman


Re: Incorrect LINENO with exported nested functions with loops

2021-10-06 Thread Tom Coleman
I was actually incorrect about something in here. Initially I discovered
the bug when this was in two scripts. I've discovered that it is actually
much simpler and nothing to do with exporting functions. Updated script is
below.

>From examination I've done to date, using BASH 5.1.8, each function is
setting up their loop COMMAND variables in order from top to bottom. The
inner for loops are done first and works outwards. For the "bad_lineno"
function, it does the arithmetic for loop first. This somehow breaks the
setting of the line number of the outer, generic for loop. I'm not familiar
with looking at things like parse.y, so I am not sure I can debug this
further and provide a fix.

#!/bin/bash
export PS4='+PS4 + L$LINENO + '
f1() {
  for d in 1 2 3; do
break
  done
}
good_lineno() {
  for i in 1; do
for j in 3; do
  :
done
  done
}
bad_lineno() {
  for k in 1; do
for ((l=3; l<=3; l++)); do
  :
done
  done
}
set -x
echo "for i in 1 line number should be 9 and is"
good_lineno
echo "for k in 1 line number should be 16 but is not"
bad_lineno

On Thu, Oct 7, 2021 at 7:43 AM L A Walsh  wrote:

>
>
> On 2021/10/05 16:25, Tom Coleman wrote
> > Repeat-By:
> > Below is a sample script to replicate the bug in LINENO.
> >
> ---
> 1st prob: scrip doesn't work as is.
> >  /tmp/lnno
> /tmp/lnno: line 23: syntax error near unexpected token `done'
> /tmp/lnno: line 23: ` done'
> 
> added the line numbers indenting and uncommenting the 2nd for loop to
> prevent the above syntax error:
>
> 01 #!/bin/bash
> 02 # vim=:SetNumberAndWidth
> 03 setx() { trap unsetx EXIT; set -x; } ; unsetx() { set +x;}
> 04 export
> PS4='>${BASH_SOURCE:+${BASH_SOURCE/$HOME/\~}}#${LINENO}${FUNCNAME:+(${FUNCNAME})}>
>
> '
> 05 setup() {
> 06   DO_BACKUP() {
> 07 for d in 1 2 3; do
> 08   break
> 09 done
> 10   }
> 11   export -f DO_BACKUP
> 12 }
> 13 run() {
> 14  for i in 1; do
> 15#for j in 1; do  # Uncomment this 'j' loop instead of the next and
> LINENO is correct
> 16for ((j=1; j<=2; j++)); do  # Uncomment this 'j' loop and LINENO
> is incorrect
> 17true
> 18done
> 19  done
> 20 }
> 21 setx
> 22 setup
> 23 run
> 24
> 25 # vim  ts=2 sw=2
>
> > The LINENO variable for the 'i' loop which is printed out by the
> > PS4 is incorrect when that DO_BACKUP function is exported, and the second
> > 'j' loop is uncommented.
> -like this, right?:
> >  /tmp/lnno
> >/tmp/lnno#22> setup
> >/tmp/lnno#11(setup)> export -f DO_BACKUP
> >/tmp/lnno#23> run
> >/tmp/lnno#25(run)> for i in 1
> >/tmp/lnno#16(run)> (( j=1 ))
> >/tmp/lnno#16(run)> (( j<=2 ))
> >/tmp/lnno#17(run)> true
> >/tmp/lnno#16(run)> (( j++ ))
> >/tmp/lnno#16(run)> (( j<=2 ))
> >/tmp/lnno#17(run)> true
> >/tmp/lnno#16(run)> (( j++ ))
> >/tmp/lnno#16(run)> (( j<=2 ))
> >/tmp/lnno#1> unsetx
> >/tmp/lnno#3(unsetx)> set +x
>
>
>
> >  If you instead uncomment the first 'j' loop, the
> > LINENO variables are correct. If DO_BACKUP does not have a loop inside
> it, the LINENO variables are all correct.
> >
> 
> So you are saying that using the 1st j loop instead of the 2nd,
> then whether or not "DO_BACKUP" has a loop inside, LINENO is correct?
> So that is what one would expect, right?.
>
> So the main problem above is the line after
> ">/tmp/lnno#23 run", where the "for i in 1" is listed as being on
> ">/tmp/lnno#25"  #(line 25)?
>
> And if DO_BACKUP is not exported, then all the line numbers are
> correct, like:
> >  /tmp/lnno
> >/tmp/lnno#23> setup
> >/tmp/lnno#24> run
> >/tmp/lnno#14(run)> for i in 1
> >/tmp/lnno#15(run)> for j in 1
> >/tmp/lnno#16(run)> DO_BACKUP
> >/tmp/lnno#7(DO_BACKUP)> for d in 1 2 3
> >/tmp/lnno#8(DO_BACKUP)> break
> >/tmp/lnno#18(run)> true
> >/tmp/lnno#1> unsetx
> >/tmp/lnno#3(unsetx)> set +x
>
>
> Yeah, that's interesting, have you tried the latest version
> of bash to see if it does the same thing?  I still need to compile it.
>
> If you export functions, they can do weird things with
> numbering.
>
> Like at your bash prompt, try:
>
>
> imafunc() { echo $LINENO; }; export -f imafunc
> echo $LINENO; imafunc; echo $LINENO
>
>
>
>
>
>
> > #!/bin/bash
> > export PS4='+L$LINENO + '
> > setup() {
> > DO_BACKUP() {
> >   for d in 1 2

Re: Incorrect LINENO with exported nested functions with loops

2021-10-06 Thread Tom Coleman
I did some experimenting and am confident on the fix. I don't know how to
supply a patch suggestion officially, but have pasted it below. Four lines
in parse.y need deleting. Arithmetic for loops should NOT be decrementing
the 'word_top' variable, they do not make use of it. This also has flow on
to select statements with nested arithmetic for loops, perhaps other
statements too, I didn't look any further. My (albeit limited) testing has
shown this fixes the line numbers for case statements and for loops.

diff --git a/parse.y b/parse.y
index df1231da..3cf2c37f 100644
--- a/parse.y
+++ b/parse.y
@@ -843,25 +843,21 @@ arith_for_command:FOR ARITH_FOR_EXPRS
list_terminator newline_list DO compound_
{
  $$ = make_arith_for_command ($2, $6,
arith_for_lineno);
  if ($$ == 0) YYERROR;
- if (word_top > 0) word_top--;
}
|   FOR ARITH_FOR_EXPRS list_terminator newline_list
'{' compound_list '}'
{
  $$ = make_arith_for_command ($2, $6,
arith_for_lineno);
  if ($$ == 0) YYERROR;
- if (word_top > 0) word_top--;
}
|   FOR ARITH_FOR_EXPRS DO compound_list DONE
{
  $$ = make_arith_for_command ($2, $4,
arith_for_lineno);
  if ($$ == 0) YYERROR;
- if (word_top > 0) word_top--;
}
|   FOR ARITH_FOR_EXPRS '{' compound_list '}'
{
  $$ = make_arith_for_command ($2, $4,
arith_for_lineno);
  if ($$ == 0) YYERROR;
- if (word_top > 0) word_top--;
}
;


Re: Incorrect LINENO with exported nested functions with loops

2021-10-07 Thread Tom Coleman
You are correct that FOR loops increment the word_top variable in the
read_token_word function, but, ARITH_FOR_EXPRS loops do not. They are
treated separately and do not increment the word_top variable from what I
can see.

#define FOR 265
#define ARITH_FOR_EXPRS 286



On Fri, Oct 8, 2021 at 7:10 AM Chet Ramey  wrote:

> On 10/7/21 12:58 AM, Tom Coleman wrote:
> > I did some experimenting and am confident on the fix. I don't know how to
> > supply a patch suggestion officially, but have pasted it below. Four
> lines
> > in parse.y need deleting. Arithmetic for loops should NOT be decrementing
> > the 'word_top' variable, they do not make use of it.
>
> I haven't looked closely at this yet, but I'm curious about your reasoning
> for the final sentence. The FOR token causes word_top to be incremented by
> read_token_word(); why should the production not decrement it after the
> entire loop is parsed?
>
> Chet
>
> --
> ``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/
>


Bash 3.x - vi repeat command broken after 4 lines

2006-04-29 Thread Tom Sorensen

Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i686'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-redhat-linux-gnu'
-DCONF_VENDOR='redhat' -DLOCALEDIR='/usr/share/locale'
-DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H  -I.  -I. -I./include -I./lib
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -pipe -m32 -march=i386
-mtune=pentium4
uname output: Linux musicbox 2.6.9-34.EL #1 Wed Mar 8 00:07:35 CST
2006 i686 athlon i386 GNU/Linux
Machine Type: i686-redhat-linux-gnu

Bash Version: 3.0
Patch Level: 15
Release Status: release

Description:
   In Bash 3.x (confirmed in 3.0 under variety of platforms and 3.1-6.2),
   when using vi-mode the repeat function (.) will stop working after a
   few lines of editing. Instead of repeating the previous command it will
   exhibit various bad behaviors (delete character under cursor or replace
   character under cursor with a different character)

Repeat-By:
   > bash
   >ls foo\ (bar)
   bash: syntax error near unexpected token `('
(type: kwwwi\ww.)
   >ls foo\ \(bar\)
   ls: foo (bar): No such file or directory
(type: kk)
   >ls foo\ (bar)
   bash: syntax error near unexpected token `('
(type: kwwwi\ww.)
   >ls foo\ \(bar  <--- This is wrong!
   ls: foo (bar: No such file or directory



Tom Sorensen


___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


aibash-0.1

2006-09-29 Thread Tom Zorn
2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  clock.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  getcwd.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  getenv.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  oslib.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  setlinebuf.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  strcasecmp.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  strerror.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  strtod.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  strtol.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  strtoul.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  vprint.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  itos.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  rename.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  zread.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  zwrite.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  shtty.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  inet_aton.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  netopen.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  strpbrk.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  timeval.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  makepath.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  pathcanon.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  pathphys.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  tmpfile.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  stringlist.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  stringvec.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  spell.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  shquote.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  strtrans.c
gcc -c  -I. -I../.. -I../.. -I../../lib -I../../include -I. -DHAVE_CONFIG_H 
-DSHELL  -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE64_SOURCE  strindex.c
rm -f libsh.a
ar cr libsh.a clktck.o clock.o getcwd.o getenv.o oslib.o setlinebuf.o 
strcasecmp.o strerror.o strtod.o strtol.o strtoul.o vprint.o itos.o rename.o 
zread.o zwrite.o shtty.o inet_aton.o netopen.o strpbrk.o timeval.o makepath.o 
pathcanon.o pathphys.o tmpfile.o stringlist.o stringvec.o spell.o shquote.o 
strtrans.o strindex.o
test -n "ranlib" && ranlib libsh.a
make[1]: Leaving directory `/home/download/aibash-0.1/lib/sh'
making lib/readline/libreadline.a in ./lib/readline
make[1]: Entering directory `/home/download/aibash-0.1/lib/readline'
rm -f readline.o
cd ./aibash && make
make[2]: Entering directory `/home/download/aibash-0.1/lib/readline/aibash'
g++ -c -g correct.cpp
In file included from correct.cpp:9:
Path.h:12: error: `string' was not declared in this scope
Path.h:12: error: ISO C++ forbids declaration of `vector' with no type
Path.h:12: error: template-id `vector< >' used as a
   declarator
Path.h:12: error: syntax error before `::' token
Path.h:16: error: syntax error before `s'
Path.h:26: error: `string' was not declared in this scope
Path.h:26: error: syntax error before `)' token
Path.h:29: error: syntax error before `)' token
Path.h:32: error: syntax error before `)' token
Path.h:42: error: syntax error before `)' token
Path.h:44: error: syntax error before `)' token
Path.h:54: error: syntax error before `)' token
Path.h: In constructor `Path::Path()':
Path.h:21: error: `pathString' undeclared (first use this function)
Path.h:21: error: (Each undeclared identifier is reported only once for each
   function it appears in.)
Path.h:22: error: `parsed' undeclared (first use this function)
Path.h: In member function `int Path::getNumOfComponents()':
Path.h:49: error: `parse' undeclared (first use this function)
Path.h:50: error: `pathComponents' undeclared (first use this function)
Path.h: At global scope:
Path.h:61: error: ISO C++ forbids defining types within return type
Path.h:61: error: syntax error before `(' token
Path.h:76: error: syntax error before `private'
Path.h:82: error: `string' was not declared in this scope
Path.h:82: error: 'vector' is used as a type, but is not defined as a type.
Path.h:85: error: `bool parsed' used prior to declaration
Path.h:88: error: 'string' is used as a type, but is not defined as a type.
Path.h:89: error: syntax error before `}' token
In file included from correct.cpp:10:
Fuzzy.h:8: error: syntax error before `&' token
In file included from correct.cpp:11:
Programs.h:7:20: hash_map: Datei oder Verzeichnis nicht gefunden
Programs.h:8:43: xercesc/sax2/DefaultHandler.hpp: Datei oder Verzeichnis nicht 
gefunden
In file included from Programs.h:9,
 from correct.cpp:11:
Program.h:10:20: hash_map: Datei oder Verzeichnis nicht gefunden
In file included from Program.h:11,
 from Programs.h:9,
 from correct.cpp:11:
Suffix.h:14: error: 'string' is used as a type, but is not defined as a type.
Suffix.h:16: error: syntax error before `name'
Suffix.h:18: error: missing ';' before right brace
Suffix.h:20: error: ISO C++ forbids defining types within return type
Suffix.h:20: error: semicolon missing after declaration of `class Suffix'
Suffix.h: In function `int Suffix()':
Suffix.h:20: error: only constructors take base initializers
Suffix.h:21: confused by earlier errors, bailing out
make[2]: *** [correct.o] Fehler 1
make[2]: Leaving directory `/home/download/aibash-0.1/lib/readline/aibash'
make[1]: *** [readline.o] Fehler 2
make[1]: Leaving directory `/home/download/aibash-0.1/lib/readline'
make: *** [lib/readline/libreadline.a] Fehler 1

Can you help me?

Thanks

Tom



___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


[PATCH] stdio buffer flushing on redirection

2007-12-30 Thread Tom Alsberg

Hi there.

A curious issue I had with a shell script writes output to a pipe, 
turns out (after quite a while of investigation, and noticing that it 
works on systems where /bin/sh is not bash) to be due to the way 
bash writes output on redirection.


Some bash builtins (e.g. echo) write output using stdio functions 
(e.g. printf, putchar), however redirection is performed at the Unix 
file descriptor level (using dup).  The thing is that since stdio 
handles buffering on its own, output of builtins may go to the wrong 
place if redirection is done.  While bash correctly takes care to 
flush the buffers after output in e.g. the echo builtin, it does not 
handle the case of output failure.


In case fflush fails, under some implementations, the output may 
remain in the stdout buffer, and when printing something later, after 
redirecting stdout to some file, the previous output (which should not 
have gone to this file) will remain in the buffer, and be printed 
together with the new output into the target file.


I managed to reduce the bug to a simple example - take the following 
script:


#!/usr/bin/env bash
trap "" 1
while true; do
   echo "FOO"
   echo "BAR" >> /tmp/barlog
done

and run it within an xterm.  As long as the terminal is still open, 
all FOO output goes to the terminal, while all BAR output goes to 
/tmp/barlog.  Close the xterm, though, and (at least with glibc 2.7 as 
the system C library), the FOO output will fail to go to the terminal 
(which no longer exists), and will instead also go to /tmp/barlog.


I believe if the terminal was closed, one would expect output to it to 
be discarded, and not go to some other unrelated file, where it may 
interfere.  If somebody can check this and let me know if you can 
reproduce the problem, or confirm that this is indeed the problem...


It does not appear easy to fix the bug in a portable way, since in 
general mixing I/O in the Unix file descriptor level and in the stdio 
level is not so well defined.  However, 4.4BSD-based systems provide 
the fpurge function, and Solaris and glibc the (identical, except for 
the return value) __fpurge function, which clears all pending output 
in a stdio FILE * buffer.  Calling those functions when redirecting 
stdout/stderr solves the problem on systems where they are supported - 
output that previously failed to go to stdout will be discarded and 
not go to the redirect target.


Attached is a small patch I wrote for bash-3.2 that (with a small 
change to configure.in and config.h.in) checks for those functions on 
configure, and if they are available uses them whenever redirecting 
stdout/stderr.  That seems to do the trick here, but let me know if it

works for you, or if there is a more correct way to do this.

I would be glad to have that patch applied to upstream bash - that 
will save us the trouble of applying it locally every time.  Of course 
it would be even better to solve that problem in a more portable 
manner, but I suspect that may require more substantial modifications 
to parts of the code.


 Cheers,
 -- Tom

--
 Tom Alsberg - hacker (being the best description fitting this space)
 Web page:  http://www.cs.huji.ac.il/~alsbergt/
DISCLAIMER:  The above message does not even necessarily represent what
my fingers have typed on the keyboard, save anything further.
diff -ur bash-3.2.orig/config.h.in bash-3.2/config.h.in
--- bash-3.2.orig/config.h.in	2006-09-12 23:00:54.0 +0300
+++ bash-3.2/config.h.in	2007-12-30 15:41:05.974625000 +0200
@@ -812,6 +812,13 @@
 /* Define if you have the wcwidth function.  */
 #undef HAVE_WCWIDTH
 
+/* Define if you have the fpurge function.  */
+#undef HAVE_FPURGE
+
+/* Define if you have the __fpurge function.  */
+#undef HAVE___FPURGE
+
+
 /* Presence of certain system include files. */
 
 /* Define if you have the  header file. */
diff -ur bash-3.2.orig/configure.in bash-3.2/configure.in
--- bash-3.2.orig/configure.in	2006-09-26 18:05:45.0 +0300
+++ bash-3.2/configure.in	2007-12-30 15:14:52.206078000 +0200
@@ -721,6 +721,9 @@
 AC_CHECK_DECLS([strcpy])
 AC_CHECK_DECLS([strsignal])
 
+dnl checks for fpurge or __fpurge
+AC_CHECK_FUNCS(fpurge __fpurge)
+
 dnl Extra test to detect the horribly broken HP/UX 11.00 strtold(3)
 AC_CHECK_DECLS([strtold], [
 AC_MSG_CHECKING([for broken strtold])
diff -ur bash-3.2.orig/redir.c bash-3.2/redir.c
--- bash-3.2.orig/redir.c	2006-05-24 05:31:35.0 +0300
+++ bash-3.2/redir.c	2007-12-30 16:35:53.627539000 +0200
@@ -31,6 +31,18 @@
 #include "filecntl.h"
 #include "posixstat.h"
 
+
+/* check for a way to clear the output buffer of a FILE *, for use
+   after dup on stdout/stderr */
+#undef	FPURGE
+#ifdef	HAVE___FPURGE
+#define	FPURGE	__fpurge
+#endif
+#ifdef	HAVE_FPURGE
+#define	FPURGE	fpurge
+#endif
+
+
 #if defined (HAVE_UNISTD_H)
 #  include 
 #endif
@@ -769,6 +781,19 @@
 	  if ((fd != redirector) && (dup2 (fd, redi

Re: stdio buffer flushing on redirection

2008-01-06 Thread Tom Alsberg

Given the recent storm of applied patches from the list, I was
wondering if anybody had the time to look at this one.  Does it do the
trick?  Is the bug at all reproducible (with the script I quoted)
elsewhere?  If there is anything that should be changed in it, or
inhibiting it from getting in, let me know.

 Thanks,
 -- Tom

On Sun, Dec 30, 2007 at 05:28:21PM +0200, Tom Alsberg wrote:

Hi there.

A curious issue I had with a shell script writes output to a pipe, 
turns out (after quite a while of investigation, and noticing that 
it works on systems where /bin/sh is not bash) to be due to the way 
bash writes output on redirection.


Some bash builtins (e.g. echo) write output using stdio functions 
(e.g. printf, putchar), however redirection is performed at the Unix 
file descriptor level (using dup).  The thing is that since stdio 
handles buffering on its own, output of builtins may go to the wrong 
place if redirection is done.  While bash correctly takes care to 
flush the buffers after output in e.g. the echo builtin, it does not 
handle the case of output failure.


In case fflush fails, under some implementations, the output may 
remain in the stdout buffer, and when printing something later, 
after redirecting stdout to some file, the previous output (which 
should not have gone to this file) will remain in the buffer, and be 
printed together with the new output into the target file.


I managed to reduce the bug to a simple example - take the following 
script:


#!/usr/bin/env bash
trap "" 1
while true; do
   echo "FOO"
   echo "BAR" >> /tmp/barlog
done

and run it within an xterm.  As long as the terminal is still open, 
all FOO output goes to the terminal, while all BAR output goes to 
/tmp/barlog.  Close the xterm, though, and (at least with glibc 2.7 
as the system C library), the FOO output will fail to go to the 
terminal (which no longer exists), and will instead also go to 
/tmp/barlog.


I believe if the terminal was closed, one would expect output to it 
to be discarded, and not go to some other unrelated file, where it 
may interfere.  If somebody can check this and let me know if you 
can reproduce the problem, or confirm that this is indeed the 
problem...


It does not appear easy to fix the bug in a portable way, since in 
general mixing I/O in the Unix file descriptor level and in the 
stdio level is not so well defined.  However, 4.4BSD-based systems 
provide the fpurge function, and Solaris and glibc the (identical, 
except for the return value) __fpurge function, which clears all 
pending output in a stdio FILE * buffer.  Calling those functions 
when redirecting stdout/stderr solves the problem on systems where 
they are supported - output that previously failed to go to stdout 
will be discarded and not go to the redirect target. 

Attached is a small patch I wrote for bash-3.2 that (with a small 
change to configure.in and config.h.in) checks for those functions 
on configure, and if they are available uses them whenever 
redirecting stdout/stderr.  That seems to do the trick here, but let 
me know if it works for you, or if there is a more correct way to do 
this.


I would be glad to have that patch applied to upstream bash - that 
will save us the trouble of applying it locally every time.  Of 
course it would be even better to solve that problem in a more 
portable manner, but I suspect that may require more substantial 
modifications to parts of the code.


 Cheers,
 -- Tom

--
 Tom Alsberg - hacker (being the best description fitting this space)
 Web page:  http://www.cs.huji.ac.il/~alsbergt/
DISCLAIMER:  The above message does not even necessarily represent what
my fingers have typed on the keyboard, save anything further.



diff -ur bash-3.2.orig/config.h.in bash-3.2/config.h.in
--- bash-3.2.orig/config.h.in   2006-09-12 23:00:54.0 +0300
+++ bash-3.2/config.h.in2007-12-30 15:41:05.974625000 +0200
@@ -812,6 +812,13 @@
 /* Define if you have the wcwidth function.  */
 #undef HAVE_WCWIDTH

+/* Define if you have the fpurge function.  */
+#undef HAVE_FPURGE
+
+/* Define if you have the __fpurge function.  */
+#undef HAVE___FPURGE
+
+
 /* Presence of certain system include files. */

 /* Define if you have the  header file. */
diff -ur bash-3.2.orig/configure.in bash-3.2/configure.in
--- bash-3.2.orig/configure.in  2006-09-26 18:05:45.0 +0300
+++ bash-3.2/configure.in   2007-12-30 15:14:52.206078000 +0200
@@ -721,6 +721,9 @@
 AC_CHECK_DECLS([strcpy])
 AC_CHECK_DECLS([strsignal])

+dnl checks for fpurge or __fpurge
+AC_CHECK_FUNCS(fpurge __fpurge)
+
 dnl Extra test to detect the horribly broken HP/UX 11.00 strtold(3)
 AC_CHECK_DECLS([strtold], [
 AC_MSG_CHECKING([for broken strtold])
diff -ur bash-3.2.orig/redir.c bash-3.2/redir.c
--- bash-3.2.orig/redir.c   2006-05-24 05:31:35.0 +0300
+++ bash-3.2/redir.c2007-12-30 16:35:53.627539000 +0200
@@ -31,6 +31,18 @@
 #include

core dump on SIGHUP

2005-06-13 Thread Tom Robinson

Configuration Information:
Machine: i686
OS: linux-gnu
Compiler: gcc
Compilation :
uname output: Linux 2.4.20-31.9 i686
Machine Type: i686-pc-linux-gnu

Bash Version: 2.05a
Patch Level: ?
Release Status: release

Description:

I have seen bash dump core a few times.  It is extremely difficult to 
reproduce naturally.
The problem occurs when a SIGHUP is received during a malloc by bash. 
After examining
the backtrace of the core, I am able to reproduce the problem using 
gbd.  I have been able to
reproduce this on a number of different platforms.  After the SIGHUP, 
bash calls a handler
to clean up, write the history, etc.  But it calls free() from 
history_do_write() which in turn
calls internal_free() where the problem occurs.  There is a comment 
right before the xbotch()

but I can't tell if that is relevant here.

Any help on this would be appreciated.

Repeat-By:

# gdb bash
   :
(gdb) break decode_prompt_string
Breakpoint 1 at 0x80600e0: file parse.y, line 3667.
(gdb) r
Starting program: bash

Breakpoint 1, decode_prompt_string (string=0x10b )
   at parse.y:3667
3667  result = (char *)xmalloc (result_size = PROMPT_GROWTH);
(gdb) c
Continuing.
[EMAIL PROTECTED] bin]# ulimit -c 10

Breakpoint 1, decode_prompt_string (string=0x10b )
   at parse.y:3667
3667  result = (char *)xmalloc (result_size = PROMPT_GROWTH);
(gdb) c
Continuing.
[EMAIL PROTECTED] bin]# ulimit -c 100

Breakpoint 1, decode_prompt_string (string=0x10b )
   at parse.y:3667
3667  result = (char *)xmalloc (result_size = PROMPT_GROWTH);
(gdb) c
Continuing.
[EMAIL PROTECTED] bin]# ls
core.23751   bash
   :

Breakpoint 1, decode_prompt_string (string=0x10b )
   at parse.y:3667
3667  result = (char *)xmalloc (result_size = PROMPT_GROWTH);
(gdb) break malloc.c:662
Breakpoint 2 at 0x80ad936: file malloc.c, line 662.
(gdb) c
Continuing.

Breakpoint 2, internal_malloc (n=48,
   file=0x80b01c0 "/usr/src/bash/src/parse.y", line=3667, flags=1)
   at malloc.c:662
662   if ((p = nextf[nunits]) == NULL)


(gdb) signal SIGHUP
Continuing with signal SIGHUP.

Breakpoint 2, internal_malloc (n=20, file=0x0, line=0, flags=0) at malloc.c:662
662   if ((p = nextf[nunits]) == NULL)
(gdb) c
Continuing.

Breakpoint 2, internal_malloc (n=42, file=0x0, line=0, flags=0) at malloc.c:662
662   if ((p = nextf[nunits]) == NULL)
(gdb) c
Continuing.

malloc: unknown:0: assertion botched
free: underflow detected; mh_nbytes out of range
last command: ls
Stopping myself...
Program received signal SIGABRT, Aborted.
0xe002 in ?? ()
(gdb) c
Continuing.

Program received signal SIGABRT, Aborted.
0xe002 in ?? ()
(gdb) bt
#0  0xe002 in ?? ()
#1  0x42028a73 in abort () from /lib/tls/libc.so.6
#2  0x0806c733 in programming_error (
   format=0x80c2b40 "free: underflow detected; mh_nbytes out of range") at
error.c:258
#3  0x080adac4 in internal_free (mem=0x80daa08, file=0x0, line=0, flags=0) at
malloc.c:759
#4  0x080adfd4 in free (mem=0x80daa08) at malloc.c:1073
#5  0x080aae93 in history_do_write (filename=0x80d3968 "/root/.bash_history",
nelements=3,
   overwrite=0) at histfile.c:381
#6  0x080aaeff in append_history (nelements=3, filename=0x80d3968
"/root/.bash_history")
   at histfile.c:398
#7  0x0808068a in maybe_save_shell_history () at bashhist.c:344
#8  0x0807c694 in termination_unwind_protect (sig=1) at sig.c:409
#9  
#10 internal_malloc (n=48, file=0x80b01c0
"/usr/src/bash/src/parse.y",
   line=3667, flags=134627174) at malloc.c:662
#11 0x080adeee in sh_malloc (bytes=48,
   file=0x80b01c0 "/usr/src/bash/src/parse.y", line=3667) at
malloc.c:987
#12 0x080890e9 in sh_xmalloc (bytes=48,
   file=0x80b01c0 "/usr/src/parse.y", line=3667) at
xmalloc.c:143
#13 0x080600fe in decode_prompt_string (string=0x80d9b48 "[EMAIL PROTECTED] \\W]\\$ 
")
   at parse.y:3667
#14 0x0806005a in prompt_again () at parse.y:3583
#15 0x0805d791 in yylex () at parse.y:1964
#16 0x0805c80e in yyparse () at bison.simple:432
#17 0x0805b7cf in parse_command () at eval.c:213
#18 0x0805b83e in read_command () at eval.c:257
#19 0x0805b583 in reader_loop () at eval.c:124
#20 0x08059beb in main (argc=1, argv=0xbfffeb74, env=0xbfffeb7c) at shell.c:668
#21 0x42015574 in __libc_start_main () from /lib/tls/libc.so.6




___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


Re: core dump on SIGHUP

2005-06-14 Thread Tom Robinson
This problem can be fixed by applying part of the update from 2.05a to 2.05b 
in
lib/malloc/malloc.c.  The relevent sections are as follows:

--- bash-2.05a.orig/lib/malloc/malloc.c 2001-10-04 12:13:16.0 +
+++ bash-2.05a/lib/malloc/malloc.c  2005-06-14 17:19:00.0 +
@@ -202,9 +202,16 @@
 #define ERR_ASSERT_FAILED  0x08

 /* Evaluates to true if NB is appropriate for bucket NU.  NB is adjusted
-   appropriately by the caller to account for malloc overhead. */
-#define IN_BUCKET(nb, nu) \
-  ((nb) > (4 << (nu)) && ((nb) <= (8 << (nu
+   appropriately by the caller to account for malloc overhead.  This only
+   checks that the recorded size is not too big for the bucket.  We
+   can't check whether or not it's in between NU and NU-1 because we
+   might have encountered a busy bucket when allocating and moved up to
+   the next size.*/
+#define IN_BUCKET(nb, nu)  ((nb) <= binsizes[(nu)])
+
+/* Use this when we want to be sure that NB is in bucket NU. */
+#define RIGHT_BUCKET(nb, nu) \
+(((nb) > binsizes[(nu)-1]) && ((nb) <= binsizes[(nu)]))

 /* nextf[i] is free list of blocks of size 2**(i + 3)  */

@@ -218,6 +225,17 @@
 static int pagebucket; /* bucket for requests a page in size */
 static int maxbuck;/* highest bucket receiving allocation request. */

+static unsigned long binsizes[NBUCKETS] = {
+   8UL, 16UL, 32UL, 64UL, 128UL, 256UL, 512UL, 1024UL, 2048UL, 4096UL,
+   8192UL, 16384UL, 32768UL, 65536UL, 131072UL, 262144UL, 524288UL,
+   1048576UL, 2097152UL, 4194304UL, 8388608UL, 16777216UL, 33554432UL,
+   67108864UL, 134217728UL, 268435456UL, 536870912UL, 1073741824UL,
+   2147483648UL, 4294967295UL
+};
+
+/* binsizes[x] == (1 << ((x) + 3)) */
+#define binsize(x)  binsizes[(x)]
+
 /* Declarations for internal functions */
 static PTR_T internal_malloc __P((size_t, const char *, int, int));
 static PTR_T internal_realloc __P((PTR_T, size_t, const char *, int, int));
@@ -753,8 +771,10 @@
  We sanity-check the value of mh_nbytes against the size of the blocks
  in the appropriate bucket before we use it.  This can still cause 
problems
  and obscure errors if mh_nbytes is wrong but still within range; the
- checks against MAGIC1 will probably fail then.  Using MALLOC_REGISTER
- will help here, since it saves the original number of bytes requested. 
*/
+ checks against the size recorded at the end of the chunk will probably
+ fail then.  Using MALLOC_REGISTER will help here, since it saves the
+ original number of bytes requested. */
+
   if (IN_BUCKET(nbytes, nunits) == 0)
 xbotch (mem, ERR_UNDERFLOW,
"free: underflow detected; mh_nbytes out of range", file, line);
@@ -837,8 +857,9 @@
  We sanity-check the value of mh_nbytes against the size of the blocks
  in the appropriate bucket before we use it.  This can still cause 
problems
  and obscure errors if mh_nbytes is wrong but still within range; the
- checks against MAGIC1 will probably fail then.  Using MALLOC_REGISTER
- will help here, since it saves the original number of bytes requested. 
*/
+ checks against the size recorded at the end of the chunk will probably
+ fail then.  Using MALLOC_REGISTER will help here, since it saves the
+ original number of bytes requested. */
   if (IN_BUCKET(nbytes, nunits) == 0)
 xbotch (mem, ERR_UNDERFLOW,
"realloc: underflow detected; mh_nbytes out of range", file, line);
@@ -851,7 +872,7 @@
   nbytes = ALLOCATED_BYTES(n);

   /* If ok, use the same block, just marking its size as changed.  */
-  if (IN_BUCKET(nbytes, nunits))
+  if (RIGHT_BUCKET(nbytes, nunits))
 {
   m = (char *)mem + tocopy;
   *m++ = 0;  *m++ = 0;  *m++ = 0;  *m++ = 0;

---
"Tom Robinson" <[EMAIL PROTECTED]> wrote in message 
news:[EMAIL PROTECTED]
...
> I have seen bash dump core a few times.  It is extremely difficult to 
> reproduce naturally.
> The problem occurs when a SIGHUP is received during a malloc by bash. 
> After examining
> the backtrace of the core, I am able to reproduce the problem using gbd. 
> I have been able to
> reproduce this on a number of different platforms.  After the SIGHUP, bash 
> calls a handler
> to clean up, write the history, etc.  But it calls free() from 
> history_do_write() which in turn
> calls internal_free() where the problem occurs.  There is a comment right 
> before the xbotch()
> but I can't tell if that is relevant here.
>
> Any help on this would be appreciated.
>
> Repeat-By:
>
> # gdb bash
>:
> (gdb) break decode_prompt_string
> Breakpoint 1 at 0x80600e0: file parse.y, line 3667.
> (gdb) r
> Starting program: bash
>
> Breakpoint 1, decode_prompt_string (string=0x10b  bounds>)
>at parse.y:3667
> 3667   result = (char *)xm

Re: [PATCH] Fix custom program's completions when initial word is set

2018-11-25 Thread Tom Ryder

On Fri, Nov 23, 2018 at 12:48:54PM +, Luca Boccassi wrote:

The fix is to only override foundcs if both iw_compspec is not null
and we are not in command position.


Thank you for this patch. I first ran into the issue with 5.0-beta2 
another way: I noticed that my default completion spec with -D as 
suggested by the Bash manual page was no longer working:


   _completion_loader()
   {
. "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124
   }
   complete -D -F _completion_loader -o bashdefault -o default

In 5.0-beta2, after running this code, for any command with no 
completion specs defined in /etc/bash_completion.d, completing an 
argument does nothing.


Your second patch does not correct that, but it looks like that's 
because a non-zero `foundcs` is coerced to 1 in it, when there are other 
meaningful values for the integer as the first parameter for 
`pcomp_set_readline_variables(int, int)`.


The attached patch is my own attempt, which seems to correct my issues 
as well as the one you raised in this post. Long-time user, first-time 
poster...


--
Tom Ryder <https://sanctum.geek.nz/>
>From f096da9756ed4d0cd8a6ef5cee02c67377891439 Mon Sep 17 00:00:00 2001
From: Tom Ryder 
Date: Sun, 25 Nov 2018 22:43:07 +1300
Subject: [PATCH] Corrections for initial word completion logic

5.0-beta2 includes a correction for the new -I option to the `complete`
builtin:

<http://lists.gnu.org/archive/html/bug-bash/2018-11/msg00035.html>

However, some custom command completion was broken by this due to an
incomplete check for the exceptional midword condition, for which a fix
was offered here:

<http://lists.gnu.org/archive/html/bug-bash/2018-11/msg00088.html>

This patch adjusts the latter fix by preventing coercion of a value of
foundcs that happens to be *greater* than 1 for this block, which also
fixes default completion with -D.
---
 bashline.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/bashline.c b/bashline.c
index d56cd79d..b3592e31 100644
--- a/bashline.c
+++ b/bashline.c
@@ -1583,7 +1583,8 @@ attempt_shell_completion (text, start, end)
  /* command completion if programmable completion fails */
  /* If we have a completion for the initial word, we can prefer that */
  in_command_position = s == start && (iw_compspec || STREQ (n, text)); 
/* XXX */
- foundcs = foundcs && (iw_compspec == 0);
+ if (iw_compspec && in_command_position)
+ foundcs = 0;
}
   /* empty command name following command separator */
   else if (s >= e && n[0] == '\0' && text[0] == '\0' && start > 0 &&
-- 
2.19.2



Re: bash-5.0-beta2 breaks ``complete -D''

2018-11-30 Thread Tom Ryder

On Fri, Nov 30, 2018 at 05:21:32PM +0800, Clark Wang wrote:
Just tried 5.0-beta2 and it broke my completion rules. It can be 
reproduced with the following steps: ...


Hello Clark; I noticed the same thing; I addressed it in an earlier 
message with the attached patch as a suggested fix, modifying a patch 
from Luca Boccassi.


<https://lists.gnu.org/archive/html/bug-bash/2018-11/msg00097.html>

- Forwarded message from Tom Ryder  -

Date: Sun, 25 Nov 2018 23:04:18 +1300
From: Tom Ryder 
To: Luca Boccassi 
Cc: bug-bash@gnu.org
Subject: Re: [PATCH] Fix custom program's completions when initial word is set

On Fri, Nov 23, 2018 at 12:48:54PM +, Luca Boccassi wrote:

The fix is to only override foundcs if both iw_compspec is not null
and we are not in command position.


Thank you for this patch. I first ran into the issue with 5.0-beta2 another
way: I noticed that my default completion spec with -D as suggested by the
Bash manual page was no longer working:

  _completion_loader()
  {
   . "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124
  }
  complete -D -F _completion_loader -o bashdefault -o default

In 5.0-beta2, after running this code, for any command with no completion
specs defined in /etc/bash_completion.d, completing an argument does nothing.

Your second patch does not correct that, but it looks like that's because a
non-zero `foundcs` is coerced to 1 in it, when there are other meaningful
values for the integer as the first parameter for
`pcomp_set_readline_variables(int, int)`.

The attached patch is my own attempt, which seems to correct my issues as well
as the one you raised in this post. Long-time user, first-time poster...

- End forwarded message -

--
Tom Ryder <https://sanctum.geek.nz/>
>From f096da9756ed4d0cd8a6ef5cee02c67377891439 Mon Sep 17 00:00:00 2001
From: Tom Ryder 
Date: Sun, 25 Nov 2018 22:43:07 +1300
Subject: [PATCH] Corrections for initial word completion logic

5.0-beta2 includes a correction for the new -I option to the `complete`
builtin:

<http://lists.gnu.org/archive/html/bug-bash/2018-11/msg00035.html>

However, some custom command completion was broken by this due to an
incomplete check for the exceptional midword condition, for which a fix
was offered here:

<http://lists.gnu.org/archive/html/bug-bash/2018-11/msg00088.html>

This patch adjusts the latter fix by preventing coercion of a value of
foundcs that happens to be *greater* than 1 for this block, which also
fixes default completion with -D.
---
 bashline.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/bashline.c b/bashline.c
index d56cd79d..b3592e31 100644
--- a/bashline.c
+++ b/bashline.c
@@ -1583,7 +1583,8 @@ attempt_shell_completion (text, start, end)
  /* command completion if programmable completion fails */
  /* If we have a completion for the initial word, we can prefer that */
  in_command_position = s == start && (iw_compspec || STREQ (n, text)); 
/* XXX */
- foundcs = foundcs && (iw_compspec == 0);
+ if (iw_compspec && in_command_position)
+ foundcs = 0;
}
   /* empty command name following command separator */
   else if (s >= e && n[0] == '\0' && text[0] == '\0' && start > 0 &&
-- 
2.19.2



bash: ^D exits immediately while jobs are stopped

2019-03-07 Thread Tom Levy
Description:

When jobs are stopped it normally takes two attempts to exit with no
intervening commands. However, if there is exactly one intervening
command, ^D exits immediately instead of printing a warning. (The
"exit" builtin works correctly on the other hand.)

Repeat-By:

$ cat
^Z
[1]+  Stopped cat
$ ^D
exit
There are stopped jobs.
$ echo intervening command
intervening command
$ ^D
exit

# expected behaviour: print "There are stopped jobs" instead of exiting

Cause:

The exit_or_logout function in builtins/exit.def uses
last_shell_builtin to check if the last command was also an exit
attempt. However, ^D bypasses the command parser so last_shell_builtin
will actually be the second to last command.

In the example above, when the second ^D is typed, this_shell_builtin
is the "echo" command and last_shell_builtin is "exit" from the first
^D. So exit_or_logout thinks this is the second exit in a row when it
isn't.

Fix:

Patch attached. It makes exit_or_logout check that this_shell_builtin
is also an exit attempt.

(The code already sets both this_shell_builtin and last_shell_builtin
to "exit" on the first exit attempt, so typing ^D twice in a row will
exit immediately like it should.)

Configuration Information:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2 -Wno-parentheses -Wno-format-security
uname output: Linux debian 4.9.0-8-amd64 #1 SMP Debian 4.9.144-3.1 (2019-02-19) 
x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 5.0
Patch Level: 2
Release Status: release

Regards,
Tom Levy
>From c4fdfa2874685685a0ba46516173abf2b5ba43ef Mon Sep 17 00:00:00 2001
From: Tom Levy <>
Date: Thu, 7 Mar 2019 04:58:18 +
Subject: [PATCH] fix ^D: don't exit while jobs are stopped after intervening
 command

---
 builtins/exit.def | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/builtins/exit.def b/builtins/exit.def
index 5167b2e0..193a6a59 100644
--- a/builtins/exit.def
+++ b/builtins/exit.def
@@ -51,6 +51,7 @@ $END
 extern int check_jobs_at_exit;
 
 static int exit_or_logout __P((WORD_LIST *));
+static int is_exit_attempt __P((sh_builtin_func_t *));
 static int sourced_logout;
 
 int
@@ -103,9 +104,8 @@ exit_or_logout (list)
   int exit_immediate_okay, stopmsg;
 
   exit_immediate_okay = (interactive  == 0 ||
-			 last_shell_builtin == exit_builtin ||
-			 last_shell_builtin == logout_builtin ||
-			 last_shell_builtin == jobs_builtin);
+			 (is_exit_attempt (this_shell_builtin) &&
+			  is_exit_attempt (last_shell_builtin)));
 
   /* Check for stopped jobs if the user wants to. */
   if (exit_immediate_okay == 0)
@@ -155,6 +155,15 @@ exit_or_logout (list)
   /*NOTREACHED*/
 }
 
+static int
+is_exit_attempt (function)
+ sh_builtin_func_t *function;
+{
+  return (function == exit_builtin ||
+	  function == logout_builtin ||
+	  function == jobs_builtin);
+}
+
 void
 bash_logout ()
 {
-- 
2.11.0



Bash 2.05 patch for "shellshock"

2014-10-03 Thread Tom Lesniak

Hi,

I'm really going out on a limb, but is there any chance of getting a 
shellshock patch for Bash 2.05? I've got many legacy systems running 
RH7.2 (enigma) that I'm trying to locate a fix for.   I've looked at the 
patches for Bash, but the fixes only go as far back as 2.05b. I've 
attempted to manually make the changes that the patches for 2.05b make, 
however there were a lot of changes between 2.05 and 2.05b so not 
everything matches.


These are legacy systems that I've got to support and upgrading to a 
newer version of Bash is not possible.


I've run the tests and this version of Bash is vulnerable.

Thanks
-Tom



Problem with sequences with variables?

2021-04-28 Thread Tom (AST) Watson
Hi...

I was trying to do some sequences, and it looks like they don't like variables. 
 See the following:
[user@box3 ~]$ echo $BASH_VERSION
5.0.17(1)-release
[user@box3 ~]$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
[user@box3 ~]$ echo $l
10
[user@box3 ~]$ echo {1..${l}}
{1..10}
[user@box3 ~]$

Shouldn't the second sequence echo be the same as the first sequence echo?  It 
would be MUCH more useful if it were.

Of course, this could be just a feature, I don't really know.  This is running 
on a Fedora 31 release build if that makes a difference.

Thanks,
...Tom Watson

More info:
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -O2 -g -pipe -Wall -Werror=format-security 
-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions 
-fstack-protector-strong -grecord-gcc-switches 
-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 
-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic 
-fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection 
-Wno-parentheses -Wno-format-security
uname output: Linux box3.appsig.com 5.7.7-100.fc31.x86_64 #1 SMP Wed Jul 1 
20:37:05 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-redhat-linux-gnu

Bash Version: 5.0
Patch Level: 17
Release Status: release

--
Tom Watson  (I'm at work now)
thomas.3.wat...@rtx.com



RE: Re: Brace expansion ordering vs. parameter expansion

2021-04-29 Thread Tom (AST) Watson
All...

I've resigned to having it the way it is, but I note that the solution doesn't 
need the backslash escape:
[tsw@box6 ~]$ k=10
[tsw@box6 ~]$ eval echo {1..$k}
1 2 3 4 5 6 7 8 9 10

I'm finding out lots of things as I go along.  Need to understand the 
"features" as they show themselves.

Thanks for the input.  It has been helpful.

...Tom
-Original Message-
From: Chet Ramey  
Sent: Thursday, April 29, 2021 07:46
To: Ilkka Virta 
Cc: chet.ra...@case.edu; Tom (AST) Watson ; 
bug-bash@gnu.org
Subject: [External] Re: Brace expansion ordering vs. parameter expansion

On 4/29/21 8:12 AM, Ilkka Virta wrote:

> Maybe, but it's never worked that way and was never intended to. You can
> get what you need using eval:
> 
> eval echo \{1..${i}}
> 
> 
> BTW, was there some background to why they're ordered like this? I'm 
> not sure if I have heard the story, and didn't see anything about it 
> in Greg's wiki or bash-hackers.org <http://bash-hackers.org> (of 
> course they tell the "what", but not the "why"). I didn't dig through all the 
> mailing lists, though.

Here's something I wrote in response to another message:

=
OK. Bash has had brace expansion in essentially its current form since 1991, 
and we chose the implementation we did with an eye towards making the code 
something that other applications could just pick up and incorporate. Korn 
chose to perform brace expansion as a component of filename expansion 
(globbing), which happens after the other word expansions. I'm sure he thought 
it was better, but he chose not to be compatible with bash.
=

I wrote 1991, but it was actually early 1989 when we (Brian and I) wrote the 
brace expansion code and put it in. We decided early on to make brace expansion 
independent of filename expansion, so you could have brace expansion even after 
performing `set -f'. There was thought towards making the brace expansion code 
reusable, in the sense that other GNU tools could take the code and easily add 
it to their argument processing. We were also reluctant to change the filename 
expansion code, which, at the time, we shared with other GNU applications 
including emacs.

So we made brace expansion a separate step, one that could be enabled and 
disabled independent of other expansions, with a defined input and output 
format, and made it happen before the POSIX word expansions. And here we are, 
thirty-plus years later.

--
``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/


Filename completion causes doubling of initial ':' character

2016-12-03 Thread Ravi (Tom) Hale

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-unknown-linux-gnu' 
-DCONF_VENDOR='unknown' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' 
-DSHELL -DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib 
-D_FORTIFY_SOURCE=2 -march=x86-64 -mtune=generic -O2 -pipe 
-fstack-protector-strong 
-DDEFAULT_PATH_VALUE='/usr/local/sbin:/usr/local/bin:/usr/bin' 
-DSTANDARD_UTILS_PATH='/usr/bin' -DSYS_BASHRC='/etc/bash.bashrc' 
-DSYS_BASH_LOGOUT='/etc/bash.bash_logout' -Wno-parentheses 
-Wno-format-security
uname output: Linux genesis 4.4.33-1-MANJARO #1 SMP PREEMPT Fri Nov 18 
18:06:44 UTC 2016 x86_64 GNU/Linux

Machine Type: x86_64-unknown-linux-gnu

Bash Version: 4.4
Patch Level: 5
Release Status: release


Description:

Given a filename called ':example'
When the user enters 'command :' and hits 
Then the completion of the filename gets a doubled colon, specifically: 
':\:example'



Repeat-By:
--
Create a filename beginning with a ':' character:

$ touch :example

Type `rm :` and hit tab, then enter.

I'd expect to see:

rm :example
[rm silently deletes it]

Instead I see:

rm :\:example
rm: cannot remove '::example': No such file or directory



Regression in pattern substitution with compat42

2023-02-08 Thread Tom Briden via Bug reports for the GNU Bourne Again SHell
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: x86_64-pc-linux-gnu-cc
Compilation CFLAGS: -march=native -O2 -pipe
uname output: Linux icarium.decompile.me.uk 6.2.0-rc7-18802-gadd2b733ea5d
#18 SMP PREEMPT_DYNAMIC Mon Feb  6 08:03:57 GMT 2023 x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 5.2
Patch Level: 15
Release Status: release

Description:
  As of version 5.2-beta, replacing a single backslash with a double
backslash is no longer possible when using BASH_COMPAT=4.2.
  The issue appears to have been introduced in commit
https://git.savannah.gnu.org/cgit/bash.git/commit/?h=devel&id=2a1c81bf634d372fde5141d7e616042ca960d9b4
  which now returns `1` from `shouldexp_replacement`.

Repeat-By:
  BASH_COMPAT=4.2; a="backslash \\"; printf "%s\n" "${a//\\/}"

  Expected output: backslash \\
  Actual output: backslash \