Re: bash segfault on unsetting bad associative array

2010-08-16 Thread Roman Rakus

 On 08/13/2010 03:55 PM, ordcoder wrote:

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   -march=x86-64 -mtune=generic -O2 -pipe
uname output: Linux ordtop 2.6.34-ARCH #1 SMP PREEMPT Wed Aug 11
00:23:15 CEST 2010 x86_64 Intel(R) Pentium(R) Dual CPU T3400 @ 2.16GHz
GenuineIntel GNU/Linux
Machine Type: x86_64-unknown-linux-gnu
Bash Version: 4.1
Patch Level: 7
Release Status: release
Description:
 Bash quietly segfaults (exit status 139) when trying to unset
associative array which was incorrectly declared (however it didn't
complain when declaring it)
 Bash compiled from sources crashed (exit status 134) under the
same circumstances with the following output:

 malloc: hashlib.c:306: assertion botched
 free: called with unallocated block argument
 last command: unset foo
 Aborting...Aborted

Repeat-By:
 # Execute the following two commands at interactive prompt or
put them in file and execute it:

 declare -A foo=bar
 unset foo


Already reported. So far, not patched.
http://www.mail-archive.com/bug-bash@gnu.org/msg06014.html

RR



Re: \c escape within $'...' can produce mangled UTF-8

2010-08-16 Thread Greg Wooledge
On Sun, Aug 15, 2010 at 02:02:05PM +0400, Dmitry Groshev wrote:
> You are wrong. Try "echo $'\x{123456}AB'" and look at the result.
> Or read the source code: lib/sh/strtans.c

The manual (bash 4.1) says:

   \xHH the eight-bit character whose value is the hexadecimal value
HH (one or two hex digits)

My bash (also 4.1) says:

imadev:~$ echo $'\x{123456}AB'
VAB

So, it looks like the undocumented feature that you asked us to test
for you is only respecting the last two hex digits inside the curly
braces.  Since none of this behavior is documented, I wouldn't count
on bash retaining that behavior in the future.



Re: [bash-bug] [bash-bug] PIPESTATUS always returns only a single element

2010-08-16 Thread Dr. Werner Fink
On Fri, Aug 13, 2010 at 12:18:23PM +0200, Werner Fink wrote:
> On Thu, Aug 12, 2010 at 05:37:55PM -0500, lstee...@gmail.com wrote:
> > #!/bin/bash
> > #
> > # A script to test PIPESTATUS and pipefail
> > #
> > echo "   cmd: set +o pipefail"
> > echo "  pipe: ps -ef 2>&1 | grep "^\$USR" >/dev/null"
> > set +o pipefail
> > ps -ef 2>&1 | grep "^$USR" >/dev/null
> > echo "expect: PIPESTATUS = 1 0 \$? = 0; got: PIPESTATUS = ${PIPESTATUS[*]} 
> > \$? = $?"
> > echo
> > echo "   cmd: set -o pipefail"
> > echo "  pipe: ps -ef 2>&1 | grep "^\$USR" >/dev/null"
> > set -o pipefail
> > ps -ef 2>&1 | grep "^$USR" >/dev/null
> > echo "expect: PIPESTATUS = 1 0 \$? = 1; got: PIPESTATUS = ${PIPESTATUS[*]} 
> > \$? = $?"
> > echo
> > echo "  pipe: ps aux 2>&1 | grep "^\$USER" >/dev/null"
> > ps aux 2>&1 | grep "^$USER" >/dev/null
> > echo "expect: PIPESTATUS = 0 0 \$? = 0; got: PIPESTATUS = ${PIPESTATUS[*]} 
> > \$? = $?"
> > echo "expect: PIPESTATUS = 0 \$? = 0; got: PIPESTATUS = ${PIPESTATUS[*]} 
> > \$? = $?"
> > #
> > # End of script
> > 
> > None of the 'got' results 'expect'ing multiple PIPESTATUS results work.
> 
> Question: could it be that you're using the bash from
> http://download.opensuse.org/repositories/shells/ or
> http://download.opensuse.org/factory/ ?
> 
> Then you may see a side effect of the patch enabling that a pipe uses
> only subshells left from that last pipe symbol.  This makes things
> work like
> 
>  bash> echo 1 2 | read a b; echo $a $b
>  1 2
> 
> ... please report such problems on the channels for opensuse.org.
> 
> Sorry Chet for the noise

The attached patch should do a better job, nevertheless IMHO there
could be a better solution.  This could require some more work
on the COMMAND API to avoid things like

 add_process((char*)0, getpid());

in execute_cmd.c, also the addjstatus() function is more like
a workaround to get the status back into the JOB/PROCESS API. 


   Werner

-- 
  "Having a smoking section in a restaurant is like having
  a peeing section in a swimming pool." -- Edward Burr
--- command.h
+++ command.h	2010-08-13 16:48:35.739125676 +0200
@@ -168,6 +168,7 @@ typedef struct element {
 #define CMD_STDIN_REDIR	   0x400 /* async command needs implicit flags |= CMD_IGNORE_RETURN;
+
+  begin_unwind_frame ("pipe-file-descriptors");
+  lstdin = -1;
+#if 1
+  if (!asynchronous && pipe_out == NO_PIPE && prev > 0
+  && cmd->type != cm_subshell && ((cmd->flags & CMD_WANT_SUBSHELL) == 0))
+{
+  lstdin = move_to_high_fd(0, 0, 255);
+  if (lstdin > 0)
+	{
+	  dup2(prev, 0);
+	  close(prev);
+	  prev = NO_PIPE;
+	  cmd->flags |= CMD_SYNC_PIPE;
+	  add_process((char*)0, getpid());
+	  stop_pipeline (0, cmd);
+	  add_unwind_protect (restore_stdin, lstdin);
+	}
+}
+#endif
+  if (prev >= 0)
+add_unwind_protect (close, prev);
+
   exec_result = execute_command_internal (cmd, asynchronous, prev, pipe_out, fds_to_close);
 
+  if (lstdin > 0)
+{
+  dup2(lstdin, 0);
+  close(lstdin);
+}
+
   if (prev >= 0)
 close (prev);
 
+  discard_unwind_frame ("pipe-file-descriptors");
+
 #if defined (JOB_CONTROL)
   UNBLOCK_CHILD (oset);
 #endif
 
+  if (cmd->flags & CMD_SYNC_PIPE)
+{
+  addjstatus(cmd, exec_result);
+  cmd->flags &= ~CMD_SYNC_PIPE;
+}
+
   QUIT;
   return (exec_result);
 }
--- jobs.c
+++ jobs.c	2010-08-16 15:48:19.479125702 +0200
@@ -260,7 +260,6 @@ static int processes_in_job __P((int));
 static void realloc_jobs_list __P((void));
 static int compact_jobs_list __P((int));
 static int discard_pipeline __P((PROCESS *));
-static void add_process __P((char *, pid_t));
 static void print_pipeline __P((PROCESS *, int, int, FILE *));
 static void pretty_print_job __P((int, int, FILE *));
 static void set_current_job __P((int));
@@ -1065,7 +1064,7 @@ nohup_job (job_index)
   if (js.j_jobslots == 0)
 return;
 
-  if (temp = jobs[job_index])
+  if ((temp = jobs[job_index]))
 temp->flags |= J_NOHUP;
 }
 
@@ -1095,7 +1094,7 @@ discard_pipeline (chain)
 /* Add this process to the chain being built in the_pipeline.
NAME is the command string that will be exec'ed later.
PID is the process id of the child. */
-static void
+void
 add_process (name, pid)
  char *name;
  pid_t pid;
@@ -3396,6 +3395,34 @@ setjstatus (j)
 #endif
 }
 
+
+void
+addjstatus(COMMAND *deferred, int status)
+{
+#if defined (ARRAY_VARS)
+  int i;
+  JOB *j;
+  for (j = jobs[(i = 0)]; j && j->deferred != deferred; j = jobs[(++i)])
+;
+  if (!j || !j->deferred)
+return;
+  j->deferred = (COMMAND*)0;
+  if (status)
+{
+  PROCESS *p, *l;
+  p = j->pipe;
+  do
+	{
+	  l = p;
+	  p = p->next;
+	}
+  while (p != j->pipe);
+  l->status = status << 8;
+}
+  setjstatus(i);
+#endif
+}
+
 void
 run_sigchld_trap (nchild)
  int nchild;
--- jobs.h
+++ jobs.h	2010-08-16 15:47:22.463125472 +0200
@@ -177,6 +177,8 @@ extern void save_pipeline __P((int));
 extern void restore_pipeline __P((int));
 extern void start_pip

Re: bash segfault on unsetting bad associative array

2010-08-16 Thread Chet Ramey
On 8/16/10 5:05 AM, Roman Rakus wrote:
>  On 08/13/2010 03:55 PM, ordcoder wrote:
>> 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   -march=x86-64 -mtune=generic -O2 -pipe
>> uname output: Linux ordtop 2.6.34-ARCH #1 SMP PREEMPT Wed Aug 11
>> 00:23:15 CEST 2010 x86_64 Intel(R) Pentium(R) Dual CPU T3400 @ 2.16GHz
>> GenuineIntel GNU/Linux
>> Machine Type: x86_64-unknown-linux-gnu
>> Bash Version: 4.1
>> Patch Level: 7
>> Release Status: release
>> Description:
>>  Bash quietly segfaults (exit status 139) when trying to unset
>> associative array which was incorrectly declared (however it didn't
>> complain when declaring it)
>>  Bash compiled from sources crashed (exit status 134) under the
>> same circumstances with the following output:
>>
>>  malloc: hashlib.c:306: assertion botched
>>  free: called with unallocated block argument
>>  last command: unset foo
>>  Aborting...Aborted
>>
>> Repeat-By:
>>  # Execute the following two commands at interactive prompt or
>> put them in file and execute it:
>>
>>  declare -A foo=bar
>>  unset foo
>>
> Already reported. So far, not patched.
> http://www.mail-archive.com/bug-bash@gnu.org/msg06014.html

Andreas posted the straightforward patch back in April.  If you want my
imprimatur, here it is.  This will be part of the next set of bash-4.1
patches.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
*** ../bash-4.1-patched/builtins/declare.def2009-11-25 19:42:00.0 
-0500
--- builtins/declare.def2010-05-30 18:25:21.0 -0400
***
*** 513,517 
  /* let bind_{array,assoc}_variable take care of this. */
  if (assoc_p (var))
!   bind_assoc_variable (var, name, "0", value, aflags);
  else
bind_array_variable (name, 0, value, aflags);
--- 519,523 
  /* let bind_{array,assoc}_variable take care of this. */
  if (assoc_p (var))
!   bind_assoc_variable (var, name, savestring ("0"), value, 
aflags);
  else
bind_array_variable (name, 0, value, aflags);