bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

expansion fails for ${#VAR[$(( 0+0 ))]}


From: jckn
Subject: expansion fails for ${#VAR[$(( 0+0 ))]}
Date: Sun, 15 Jan 2006 16:13:00 +0100
User-agent: Mutt/1.5.11

Configuration Information [Automatically generated, do not change]:
Machine: i486
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i486' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i486-pc-linux-gnu' 
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -
DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H   -I.  -I../bash -I../bash/include 
-I../bash/lib   -g -O2
uname output: Linux hejre 2.6.15 #3 PREEMPT Tue Jan 10 12:50:16 CET 2006 i686 
GNU/Linux
Machine Type: i486-pc-linux-gnu

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

Description:
A parameter expression where you want to take _the length of_ an array
member whose index is calculated at the same time fails to expand
with the following error:

jcn@hejre:/usr/share/doc/bash$ echo ${LOGNAME[$(( 0+0 ))]}
jcn
jcn@hejre:/usr/share/doc/bash$ echo ${#LOGNAME[$(( 0+0 ))]}
-bash: ${#LOGNAME[$(( 0+0 ))]}: bad substitution

Repeat-By:
See above.

Fix:
Here's the beginning of subst.c:parameter_brace_expand():

   5779 static WORD_DESC *
   5780 parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, 
contains_dollar_at)
   5781      char *string;
   5782      int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at;
   5783 {
   5784   int check_nullness, var_is_set, var_is_null, var_is_special;
   5785   int want_substring, want_indir, want_patsub;
   5786   char *name, *value, *temp, *temp1;
   5787   WORD_DESC *tdesc, *ret;
   5788   int t_index, sindex, c, tflag;
   5789   intmax_t number;
   5790
   5791   value = (char *)NULL;
   5792   var_is_set = var_is_null = var_is_special = check_nullness = 0;
   5793   want_substring = want_indir = want_patsub = 0;
   5794
   5795   sindex = *indexp;
   5796   t_index = ++sindex;
   5797   name = string_extract (string, &t_index, "#%:-=?+/}", EX_VARNAME);
   5798
   5799   ret = 0;
   5800   tflag = 0;
   5801
   5802   /* If the name really consists of a special variable, then make sure
   5803      that we have the entire name.  We don't allow indirect references
   5804      to special variables except `#', `?', `@' and `*'. */
   5805   if ((sindex == t_index &&
   5806         (string[t_index] == '-' ||
   5807          string[t_index] == '?' ||
   5808          string[t_index] == '#')) ||
   5809       (sindex == t_index - 1 && string[sindex] == '!' &&
   5810         (string[t_index] == '#' ||
   5811          string[t_index] == '?' ||
   5812          string[t_index] == '@' ||
   5813          string[t_index] == '*')))
   5814     {
   5815       t_index++;
   5816       free (name);
   5817       temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
   5818       name = (char *)xmalloc (3 + (strlen (temp1)));
   5819       *name = string[sindex];
   5820       if (string[sindex] == '!')
   5821         {
   5822           /* indirect reference of $#, $?, $@, or $* */
   5823           name[1] = string[sindex + 1];
   5824           strcpy (name + 2, temp1);
   5825         }
   5826       else
   5827         strcpy (name + 1, temp1);
   5828       free (temp1);
   5829     }
   5830   sindex = t_index;

Assume string = "#LOGNAME[$(( 0+0 ))]}", as in my example above.
Then, in 5797, name = "" and still sindex == t_index.
So the code enters the if-block at 5805 (string[t_index] == '#'),
and in 5817

temp1 = "#LOGNAME[$(( 0"

because the fourth parameter is 0 and not EX_VARNAME, as I'd have
expected. With this content of temp1 (which is then copied back to
name), the later expansion(s) are bound to fail.

I've attached my suggested patch (one-liner, changing the mentioned
fourth parameter).


Regards,

Jan

Attachment: bash_subst.patch
Description: Text document


reply via email to

[Prev in Thread] Current Thread [Next in Thread]