1/6/2019
--------
-execute_cmd.c
- - execute_simple_command: catch all non-zero special builtin errors
- (e.g. return not in a function) and make sure a non-interactive
- posix-mode shell exits. Old code expected builtins to signal
- internal fatal errors with code > 256. Fixes bug reported by
- Robert Hailey <bash@osndok.com>
examples/loadables/basename.c
- make sure to include bashgetopt.h. Reported by Angel
- u32toutf16: correct the second argument to be wchar_t *, and treat
it as such, even though it doesn't make a difference in practice.
Report and fix from Eduardo Bustamante <dualbus@gmail.com>
+
+ 1/8
+ ---
+
+builtins/return.def
+ - return_builtin: return EX_USAGE if we're not executing a shell
+ function or sourcing a script, so a posix-mode shell exits. Fixes
+ bug reported by Robert Hailey <bash@osndok.com>
+
+builtins/declare.def
+ - declare_internal: don't let `declare -f +f' turn off the function
+ attribute. Fix from Grisha Levit <grishalevit@gmail.com>
+ - declare_internal: reject attempts to add the -A or -a attributes
+ to functions. Report from Grisha Levit <grishalevit@gmail.com>
+
+ 1/9
+ ---
+bashline.c
+ - completion_glob_pattern: new function, returns true if the passed
+ string contains a glob pattern that should be process by the glob
+ completion code. Completion glob patterns don't pay attention to
+ backslashes unless they're the last character in the string. This
+ is a different, more self-contained, fix for the problem reported
+ by Tom Ryder <tom@sanctum.geek.nz>
+
+lib/glob/glob_loop.c
+ - INTERNAL_GLOB_PATTERN_P: restore change from 4/27 and make this
+ function return non-zero if it encounters a backslash in the string.
+ It needs to match pathexp.c:unquoted_glob_pattern_p(). Adds fix
+ back for issue reported by axel@freakout.de
+
+test.c
+ - arithcomp: when calling evalexp, make sure to call it with the
+ EXP_EXPANDED flag, since all arguments here have been evaluated
+ already
+
+arrayfunc.c
+ - array_expand_index: call evalexp with EXP_EXPANDED flag, since we
+ have run the string through expand_arith_string already
t = expand_arith_string (exp, Q_DOUBLE_QUOTES|Q_ARITH|Q_ARRAYSUB); /* XXX - Q_ARRAYSUB for future use */
savecmd = this_command_name;
this_command_name = (char *)NULL;
- val = evalexp (t, 0, &expok);
+ val = evalexp (t, EXP_EXPANDED, &expok); /* XXX - was 0 but we expanded exp already */
this_command_name = savecmd;
if (t != exp)
free (t);
/* bashline.c -- Bash's interface to the readline library. */
-/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2019 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
static int bash_complete_command __P((int, int));
static int bash_possible_command_completions __P((int, int));
+static int completion_glob_pattern __P((const char *));
static char *glob_complete_word __P((const char *, int));
static int bash_glob_completion_internal __P((int));
static int bash_glob_complete_word __P((int, int));
/* This could be a globbing pattern, so try to expand it using pathname
expansion. */
- if (!matches && glob_pattern_p (text))
+ if (!matches && completion_glob_pattern (text))
{
matches = rl_completion_matches (text, glob_complete_word);
/* A glob expression that matches more than one filename is problematic.
glob_matches = (char **)NULL;
}
- globpat = glob_pattern_p (hint_text);
+ globpat = completion_glob_pattern (hint_text);
/* If this is an absolute program name, do not check it against
aliases, reserved words, functions or builtins. We must check
return bash_specific_completion (what_to_do, command_word_completion_function);
}
+static int
+completion_glob_pattern (string)
+ const char *string;
+{
+ register int c;
+ char *send;
+ int open;
+
+ DECLARE_MBSTATE;
+
+ open = 0;
+ send = string + strlen (string);
+
+ while (c = *string++)
+ {
+ switch (c)
+ {
+ case '?':
+ case '*':
+ return (1);
+
+ case '[':
+ open++;
+ continue;
+
+ case ']':
+ if (open)
+ return (1);
+ continue;
+
+ case '+':
+ case '@':
+ case '!':
+ if (*string == '(') /*)*/
+ return (1);
+ continue;
+
+ case '\\':
+ if (*string == 0)
+ return (0);
+ }
+
+ /* Advance one fewer byte than an entire multibyte character to
+ account for the auto-increment in the loop above. */
+#ifdef HANDLE_MULTIBYTE
+ string--;
+ ADVANCE_CHAR_P (string, send - string);
+ string++;
+#else
+ ADVANCE_CHAR_P (string, send - string);
+#endif
+ }
+ return (0);
+}
+
static char *globtext;
static char *globorig;
t = substring (rl_line_buffer, p, rl_point);
}
- if (t && glob_pattern_p (t) == 0)
+ if (t && completion_glob_pattern (t) == 0)
rl_explicit_arg = 1; /* XXX - force glob_complete_word to append `*' */
FREE (t);
any_failed++;
NEXT_VARIABLE ();
}
-
+ else if (flags_on & (att_array|att_assoc))
+ {
+ sh_invalidopt ((flags_on & att_array) ? "-a" : "-A");
+ any_failed++;
+ NEXT_VARIABLE ();
+ }
/* declare -[Ff] name [name...] */
if (flags_on == att_function && flags_off == 0)
{
else /* declare -[fF] -[rx] name [name...] */
{
VSETATTR (var, flags_on);
+ flags_off &= ~att_function; /* makes no sense */
VUNSETATTR (var, flags_off);
}
}
else
{
builtin_error (_("can only `return' from a function or sourced script"));
- return (EXECUTION_FAILURE);
+ return (EX_USAGE);
}
}
extern int errno;
#endif
-extern int dollar_dollar_pid;
+extern pid_t dollar_dollar_pid;
extern int last_command_exit_value;
int
if (builtin_is_special)
special_builtin_failed = 1; /* XXX - take command builtin into account? */
}
- else
- special_builtin_failed = builtin_is_special && result != EXECUTION_SUCCESS;
/* In POSIX mode, if there are assignment statements preceding
a special builtin, they persist after the builtin
continue;
case L('\\'):
-#if 0
/* Don't let the pattern end in a backslash (GMATCH returns no match
if the pattern ends in a backslash anyway), but otherwise return 1,
since the matching engine uses backslash as an escape character
and it can be removed. */
return (*p != L('\0'));
-#else
- /* The pattern may not end with a backslash. */
- if (*p++ == L('\0'))
- return 0;
-#endif
}
return 0;
/* This is expanded version of expand_string_internal as it's called by
expand_string_leave_quoted */
td.flags = W_NOPROCSUB|W_NOTILDE; /* don't want process substitution or tilde expansion */
+#if 0 /* TAG:bash-5.1 */
+ if (quoted & Q_ARRAYSUB)
+ td.flags |= W_NOCOMSUB;
+#endif
td.word = savestring (string);
list = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
/* This takes care of the calls from expand_string_leave_quoted and
if (flags & TEST_ARITHEXP)
{
- l = evalexp (s, 0, &expok);
+ l = evalexp (s, EXP_EXPANDED, &expok);
if (expok == 0)
return (FALSE); /* should probably longjmp here */
- r = evalexp (t, 0, &expok);
+ r = evalexp (t, EXP_EXPANDED, &expok);
if (expok == 0)
return (FALSE); /* ditto */
}
argv[1] = <a\?>
a?
aa
+<define\/\
+/>
argv[1] = <a>
argv[2] = <abc>
argv[3] = <abd>
var='a\a'
printf "%s\n" ${var}
+
+# shell's idea of a glob pattern and libglob's idea of a glob pattern have to
+# be identical
+PRE='\/'
+printf '<%s>\n' 'define'${PRE}'\
+/'