Re: wrong variable name in error message about unbound variable?
On 10/17/23 3:32 PM, Grisha Levit wrote: The reason is that if there was no variable found prior to expanding the subscript, bash does not check to see if one was created during that process. Thanks, I'll consider it. Behavior varies across shells in this area. 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/
Re: bash tries to parse comsub in quoted PE pattern
On 10/18/23 1:08 PM, Emanuele Torre wrote: On Wed, Oct 18, 2023 at 11:24:11AM -0400, Chet Ramey wrote: On 10/18/23 10:50 AM, Chet Ramey wrote: Is it really ok to break that behaviour? That's why, if you want the first problem repaired, you have to specify which word expansions are ok to parse and which are not. Should it be only command and process substitution, which can independently specify brace expansions? Should it be other parameter expansions, which can contain quoted strings and command substitutions? Neither? Both? It looks like the answer is probably "neither." I have examined the code, and I now understand why "${foo:-"{1..2}"}" etc were allowed, but were not supposed to. We can get closer with changes to how the command substitutions are parsed while performing brace expansion. While we are at it, when examining this issue now, I have also noticed that, regardless of whether brace expansion is enabled or not, the bash parser always reads single quotes in double quoted PEs as if they are not literal, even though they are literal if the PE is -, =, or +. [...] Could/Should this also be fixed so that "${foo:-'}" (and +, and =) is read correctly? Other shells including ksh93, mksh, dash, NetBSD ash, and busybox can read it correctly. It behaves as you want in posix mode. Here's the comment explaning it: /* The big hammer. Single quotes aren't special in double quotes. The problem is that Posix used to say the single quotes are semi-special: within a double-quoted ${...} construct "an even number of unescaped double-quotes or single-quotes, if any, shall occur." */ /* This was changed in Austin Group Interp 221 */ Bash in default mode uses its historical behavior, which is what POSIX originally specified. -- ``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: wrong variable name in error message about unbound variable?
On Thu, Oct 19, 2023, 16:58 Chet Ramey wrote: > On 10/17/23 3:32 PM, Grisha Levit wrote: > > > The reason is that if there was no variable found prior to expanding > > the subscript, bash does not check to see if one was created during > > that process. > > Thanks, I'll consider it. Behavior varies across shells in this area. > to me , its a valid err of non exist value another normal is to || true with like = or := ah i suggest an shopt , cause imo both approaches are valid but different greets 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/ > > >
[PATCH] printf %ls/%lc/%Q fixes
A few issues with handling of the new %ls, %lc and %Q conversion specifications: The %ls and %lc conversion specifications dereference a null pointer if used without an argument: $ (printf %ls) Segmentation fault: 11 $ (printf %lc) Segmentation fault: 11 The Q conversion specifier's precision handling applies when precision is provided as part of the format string, but not when it comes form an argument: $ printf '%.1Q\n' '**' \* $ printf '%.*Q\n' 1 '**' \*\* There is code to handle integer overflow for precision values by capping values to INT_MAX but it's broken for the %Q conversion specifier due to reading the value into an int rather than an intmax_t prior to overflow checks being applied: $ INT_MAX=$(getconf INT_MAX) OVERFLOW=$((INT_MAX*2 + 3)) $ printf "%.${OVERFLOW}s" XY XY $ printf "%.${OVERFLOW}Q" XY X A precision value of 0 is ignored for the %ls conversion specification: $ printf '[%.0s][%.0ls]' X Y [][Y] A null argument to the %lc conversion specifier does not produce a null byte. Per discussion in [1], Bash's behavior matches the standard as it was written, but this is now considered a defect. $ printf '[%c][%lc]' '' '' | cat -v [^@][] [1] https://austingroupbugs.net/view.php?id=1647 --- builtins/printf.def | 38 ++ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/builtins/printf.def b/builtins/printf.def index ae6c75c5..6d3fd9a4 100644 --- a/builtins/printf.def +++ b/builtins/printf.def @@ -252,12 +252,13 @@ static size_t conv_bufsize; static inline int decodeprec (char *ps) { - int mpr; + intmax_t mpr; mpr = *ps++ - '0'; while (DIGIT (*ps)) mpr = (mpr * 10) + (*ps++ - '0'); - return mpr; + /* Error if precision > INT_MAX here? */ + return (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr; } int @@ -490,7 +491,10 @@ printf_builtin (WORD_LIST *list) ws[0] = wc; ws[1] = L'\0'; - r = printwidestr (start, ws, 1, fieldwidth, precision); + if (wc == L'\0') + r = printstr (start, ws, 1, fieldwidth, precision); + else + r = printwidestr (start, ws, 1, fieldwidth, precision); if (r < 0) PRETURN (EXECUTION_FAILURE); break; @@ -514,7 +518,7 @@ printf_builtin (WORD_LIST *list) wp = getwidestr (&slen); r = printwidestr (start, wp, slen, fieldwidth, precision); - free (wp); + FREE (wp); if (r < 0) PRETURN (EXECUTION_FAILURE); break; @@ -647,20 +651,19 @@ printf_builtin (WORD_LIST *list) case 'Q': { char *p, *xp; - int r, mpr; + int r; size_t slen; r = 0; p = getstr (); /* Decode precision and apply it to the unquoted string. */ - if (convch == 'Q' && precstart) + if (convch == 'Q' && (have_precision || precstart)) { - mpr = decodeprec (precstart); - /* Error if precision > INT_MAX here? */ - precision = (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr; + if (precstart) + precision = decodeprec (precstart); slen = strlen (p); /* printf precision works in bytes. */ - if (precision < slen) + if (precision >= 0 && precision < slen) p[precision] = '\0'; } if (p && *p == 0) /* XXX - getstr never returns null */ @@ -1517,6 +1520,14 @@ getwidestr (size_t *lenp) wchar_t *ws; const char *mbs; size_t slen, mblength; + + if (garglist == 0) +{ + if (lenp) + *lenp = 0; + return NULL; +} + DECLARE_MBSTATE; mbs = garglist->word->word; @@ -1545,8 +1556,11 @@ getwidechar (void) { wchar_t wc; size_t slen, mblength; - DECLARE_MBSTATE; + if (garglist == 0) +return L'\0'; + + DECLARE_MBSTATE; wc = 0; mblength = mbrtowc (&wc, garglist->word->word, locale_mb_cur_max, &state); if (MB_INVALIDCH (mblength)) @@ -1571,7 +1585,7 @@ convwidestr (wchar_t *ws, int prec) ts = (const wchar_t *)ws; - if (prec > 0) + if (prec >= 0) { rsize = prec * MB_CUR_MAX; ret = (char *)xmalloc (rsize + 1); -- 2.42.0
Re: using a variable from global scope or checking whether it is local to some scope
On Thu, Oct 19, 2023, 23:42 Christoph Anton Mitterer wrote: > Hey Alex. > > On Thu, 2023-10-19 at 22:17 +0200, alex xmb sw ratchev wrote: > > another answer > > in ur code , force global / local whenever u need it > > > > ~ $ ( declare -g a ; a=2 ; declare -p a ; declare a ; declare -p a ; > > a=3 ) > > declare -- a="2" > > declare -- a="2" > > ~ $ > > > > sadly i didnt find difference there > > but just declare -g or non -g when u need > > I don't understand how this should help? > Yes it allows me to set the global one, but I cannot expand it? > 1 i mean when u need a change of local to global back u add this to the code .. 2 it seems me bug in bash : ~ $ ( declare -g a ; a=2 ; declare -p a ; declare a ; a=3 ; declare -p a ; declare -g a ; declare -p a ; a=4 ; declare -p a ) declare -- a="2" declare -- a="3" declare -- a="3" declare -- a="4" the third is from local back global , but it says value of local ( 3 ) and not original value ( 2 ) a=global > > other() > { >local a=from_other >mine >echo $a > } > > mine() > { >echo $a >( declare -g a ; echo $a; declare -p a ) > > } > > echo $a > other > > > gives: > global > from_other > from_other > declare -- a="from_other" > from_other > > > > Cheers, > Chris. > >
[PATCH] printf width/precision argument overflow
When reading a printf width/precision argument, the value isn't checked for overflow if it happens to be the last argument: $ INT_MAX=$(getconf INT_MAX) $ printf '[%*s]' "$((INT_MAX+1))" [] $ printf '[%*s]' "$((INT_MAX+1))" X -bash: printf: X: Result too large [] ..and the following argument is used in the error message if it exists. --- builtins/printf.def | 23 +++ 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/builtins/printf.def b/builtins/printf.def index 6d3fd9a4..5030b788 100644 --- a/builtins/printf.def +++ b/builtins/printf.def @@ -1343,13 +1343,27 @@ static int getint (void) { intmax_t ret; - - ret = getintmax (); + char *ep; if (garglist == 0) -return ret; +return (0); + + if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') +return asciicode (); - if (ret > INT_MAX) + errno = 0; + ret = strtoimax (garglist->word->word, &ep, 0); + + if (*ep) +{ + sh_invalidnum (garglist->word->word); + conversion_error = 1; +} + else if (errno == ERANGE) +{ + printf_erange (garglist->word->word); +} + else if (ret > INT_MAX) { printf_erange (garglist->word->word); ret = INT_MAX; @@ -1360,6 +1374,7 @@ getint (void) ret = INT_MIN; } + garglist = garglist->next; return ((int)ret); } -- 2.42.0