source: patches/bash-3.2-fixes-6.patch@ c30178f

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since c30178f was 5cd07a2, checked in by Jim Gifford <clfs@…>, 17 years ago

Updated Bash 3.2 Patch to -6

  • Property mode set to 100644
File size: 49.2 KB
RevLine 
[5cd07a2]1Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
2Date: 2007-09-04
[24cc73c]3Initial Package Version: 3.2
4Origin: ftp://ftp.cwru.edu/pub/bash/bash-3.2-patches/
5Upstream Status: From Upstream
[5cd07a2]6Description: Contains patches 001-025 from upstream
[24cc73c]7
8diff -Naur bash-3.2.orig/array.c bash-3.2/array.c
[5cd07a2]9--- bash-3.2.orig/array.c 2005-06-01 13:39:22.000000000 -0700
10+++ bash-3.2/array.c 2007-09-03 21:59:25.000000000 -0700
[24cc73c]11@@ -120,7 +120,6 @@
12 return(a1);
13 }
14
15-#ifdef INCLUDE_UNUSED
16 /*
17 * Make and return a new array composed of the elements in array A from
18 * S to E, inclusive.
19@@ -141,13 +140,12 @@
20 for (p = s, i = 0; p != e; p = element_forw(p), i++) {
21 n = array_create_element (element_index(p), element_value(p));
22 ADD_BEFORE(a->head, n);
23- mi = element_index(ae);
24+ mi = element_index(n);
25 }
26 a->num_elements = i;
27 a->max_index = mi;
28 return a;
29 }
30-#endif
31
32 /*
33 * Walk the array, calling FUNC once for each element, with the array
34@@ -300,6 +298,23 @@
35 return array;
36 }
37
38+ARRAY *
39+array_quote_escapes(array)
40+ARRAY *array;
41+{
42+ ARRAY_ELEMENT *a;
43+ char *t;
44+
45+ if (array == 0 || array_head(array) == 0 || array_empty(array))
46+ return (ARRAY *)NULL;
47+ for (a = element_forw(array->head); a != array->head; a = element_forw(a)) {
48+ t = quote_escapes (a->value);
49+ FREE(a->value);
50+ a->value = t;
51+ }
52+ return array;
53+}
54+
55 /*
56 * Return a string whose elements are the members of array A beginning at
57 * index START and spanning NELEM members. Null elements are counted.
58@@ -311,9 +326,10 @@
59 arrayind_t start, nelem;
60 int starsub, quoted;
61 {
62+ ARRAY *a2;
63 ARRAY_ELEMENT *h, *p;
64 arrayind_t i;
65- char *ifs, sep[2];
66+ char *ifs, sep[2], *t;
67
68 p = a ? array_head (a) : 0;
69 if (p == 0 || array_empty (a) || start > array_max_index(a))
70@@ -336,6 +352,13 @@
71 for (i = 0, h = p; p != a->head && i < nelem; i++, p = element_forw(p))
72 ;
73
74+ a2 = array_slice(a, h, p);
75+
76+ if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
77+ array_quote(a2);
78+ else
79+ array_quote_escapes(a2);
80+
81 if (starsub && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) {
82 ifs = getifs();
83 sep[0] = ifs ? *ifs : '\0';
84@@ -343,7 +366,10 @@
85 sep[0] = ' ';
86 sep[1] = '\0';
87
88- return (array_to_string_internal (h, p, sep, quoted));
89+ t = array_to_string (a2, sep, 0);
90+ array_dispose(a2);
91+
92+ return t;
93 }
94
95 char *
96@@ -367,7 +393,9 @@
97 }
98
99 if (mflags & MATCH_QUOTED)
100- array_quote (a2);
101+ array_quote(a2);
102+ else
103+ array_quote_escapes(a2);
104 if (mflags & MATCH_STARSUB) {
105 ifs = getifs();
106 sifs[0] = ifs ? *ifs : '\0';
107diff -Naur bash-3.2.orig/array.h bash-3.2/array.h
[5cd07a2]108--- bash-3.2.orig/array.h 2003-06-01 12:50:30.000000000 -0700
109+++ bash-3.2/array.h 2007-09-03 21:59:25.000000000 -0700
[24cc73c]110@@ -55,6 +55,7 @@
111 extern ARRAY_ELEMENT *array_unshift_element __P((ARRAY *));
112 extern int array_shift_element __P((ARRAY *, char *));
113 extern ARRAY *array_quote __P((ARRAY *));
114+extern ARRAY *array_quote_escapes __P((ARRAY *));
115
116 extern char *array_subrange __P((ARRAY *, arrayind_t, arrayind_t, int, int));
117 extern char *array_patsub __P((ARRAY *, char *, char *, int));
[5cd07a2]118diff -Naur bash-3.2.orig/arrayfunc.c bash-3.2/arrayfunc.c
119--- bash-3.2.orig/arrayfunc.c 2006-07-27 06:37:59.000000000 -0700
120+++ bash-3.2/arrayfunc.c 2007-09-03 21:59:34.000000000 -0700
121@@ -618,6 +618,8 @@
122 if (expok == 0)
123 {
124 last_command_exit_value = EXECUTION_FAILURE;
125+
126+ top_level_cleanup ();
127 jump_to_top_level (DISCARD);
128 }
129 return val;
[24cc73c]130diff -Naur bash-3.2.orig/builtins/common.c bash-3.2/builtins/common.c
[5cd07a2]131--- bash-3.2.orig/builtins/common.c 2006-07-27 06:39:51.000000000 -0700
132+++ bash-3.2/builtins/common.c 2007-09-03 21:59:34.000000000 -0700
[24cc73c]133@@ -1,4 +1,4 @@
134-/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
135+/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
136
137 This file is part of GNU Bash, the Bourne Again SHell.
138
[5cd07a2]139@@ -131,6 +131,7 @@
140 if (list)
141 {
142 builtin_error (_("too many arguments"));
143+ top_level_cleanup ();
144 jump_to_top_level (DISCARD);
145 }
146 }
147@@ -395,7 +396,10 @@
148 if (fatal)
149 throw_to_top_level ();
150 else
151- jump_to_top_level (DISCARD);
152+ {
153+ top_level_cleanup ();
154+ jump_to_top_level (DISCARD);
155+ }
156 }
157 no_args (list->next);
158 }
159@@ -475,7 +479,11 @@
[24cc73c]160
161 if (the_current_working_directory == 0)
162 {
163+#if defined (GETCWD_BROKEN)
164+ the_current_working_directory = getcwd (0, PATH_MAX);
165+#else
166 the_current_working_directory = getcwd (0, 0);
167+#endif
168 if (the_current_working_directory == 0)
169 {
170 fprintf (stderr, _("%s: error retrieving current directory: %s: %s\n"),
171diff -Naur bash-3.2.orig/builtins/printf.def bash-3.2/builtins/printf.def
[5cd07a2]172--- bash-3.2.orig/builtins/printf.def 2006-09-18 05:48:42.000000000 -0700
173+++ bash-3.2/builtins/printf.def 2007-09-03 21:59:23.000000000 -0700
[24cc73c]174@@ -1,7 +1,7 @@
175 This file is printf.def, from which is created printf.c.
176 It implements the builtin "printf" in Bash.
177
178-Copyright (C) 1997-2005 Free Software Foundation, Inc.
179+Copyright (C) 1997-2007 Free Software Foundation, Inc.
180
181 This file is part of GNU Bash, the Bourne Again SHell.
182
183@@ -49,6 +49,12 @@
184 # define INT_MIN (-2147483647-1)
185 #endif
186
187+#if defined (PREFER_STDARG)
188+# include <stdarg.h>
189+#else
190+# include <varargs.h>
191+#endif
192+
193 #include <stdio.h>
194 #include <chartypes.h>
195
196@@ -64,6 +70,10 @@
197 #include "bashgetopt.h"
198 #include "common.h"
199
200+#if defined (PRI_MACROS_BROKEN)
201+# undef PRIdMAX
202+#endif
203+
204 #if !defined (PRIdMAX)
205 # if HAVE_LONG_LONG
206 # define PRIdMAX "lld"
207@@ -151,6 +161,10 @@
208 #define SKIP1 "#'-+ 0"
209 #define LENMODS "hjlLtz"
210
211+#ifndef HAVE_ASPRINTF
212+extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
213+#endif
214+
215 static void printf_erange __P((char *));
216 static int printstr __P((char *, char *, int, int, int));
217 static int tescape __P((char *, char *, int *));
[5cd07a2]218diff -Naur bash-3.2.orig/builtins/read.def bash-3.2/builtins/read.def
219--- bash-3.2.orig/builtins/read.def 2006-09-19 05:45:48.000000000 -0700
220+++ bash-3.2/builtins/read.def 2007-09-03 21:59:36.000000000 -0700
221@@ -127,14 +127,14 @@
222 WORD_LIST *list;
223 {
224 register char *varname;
225- int size, i, nr, pass_next, saw_escape, eof, opt, retval, code;
226- int input_is_tty, input_is_pipe, unbuffered_read;
227+ int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
228+ int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
229 int raw, edit, nchars, silent, have_timeout, fd;
230 unsigned int tmout;
231 intmax_t intval;
232 char c;
233 char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
234- char *e, *t, *t1;
235+ char *e, *t, *t1, *ps2;
236 struct stat tsb;
237 SHELL_VAR *var;
238 #if defined (ARRAY_VARS)
239@@ -148,6 +148,7 @@
240 USE_VAR(size);
241 USE_VAR(i);
242 USE_VAR(pass_next);
243+ USE_VAR(print_ps2);
244 USE_VAR(saw_escape);
245 USE_VAR(input_is_pipe);
246 /* USE_VAR(raw); */
247@@ -163,6 +164,7 @@
248 USE_VAR(rlind);
249 #endif
250 USE_VAR(list);
251+ USE_VAR(ps2);
252
253 i = 0; /* Index into the string that we are reading. */
254 raw = edit = 0; /* Not reading raw input by default. */
255@@ -386,7 +388,8 @@
256 setmode (0, O_TEXT);
257 #endif
258
259- for (eof = retval = 0;;)
260+ ps2 = 0;
261+ for (print_ps2 = eof = retval = 0;;)
262 {
263 #if defined (READLINE)
264 if (edit)
265@@ -412,6 +415,15 @@
266 {
267 #endif
268
269+ if (print_ps2)
270+ {
271+ if (ps2 == 0)
272+ ps2 = get_string_value ("PS2");
273+ fprintf (stderr, "%s", ps2 ? ps2 : "");
274+ fflush (stderr);
275+ print_ps2 = 0;
276+ }
277+
278 if (unbuffered_read)
279 retval = zread (fd, &c, 1);
280 else
281@@ -440,7 +452,11 @@
282 {
283 pass_next = 0;
284 if (c == '\n')
285- i--; /* back up over the CTLESC */
286+ {
287+ i--; /* back up over the CTLESC */
288+ if (interactive && input_is_tty && raw == 0)
289+ print_ps2 = 1;
290+ }
291 else
292 goto add_char;
293 continue;
[24cc73c]294diff -Naur bash-3.2.orig/config-bot.h bash-3.2/config-bot.h
[5cd07a2]295--- bash-3.2.orig/config-bot.h 2006-09-12 13:43:04.000000000 -0700
296+++ bash-3.2/config-bot.h 2007-09-03 21:59:22.000000000 -0700
[24cc73c]297@@ -1,7 +1,7 @@
298 /* config-bot.h */
299 /* modify settings or make new ones based on what autoconf tells us. */
300
301-/* Copyright (C) 1989-2002 Free Software Foundation, Inc.
302+/* Copyright (C) 1989-2007 Free Software Foundation, Inc.
303
304 This file is part of GNU Bash, the Bourne Again SHell.
305
306@@ -70,9 +70,11 @@
307 # define TERMIOS_MISSING
308 #endif
309
310-/* If we have a getcwd(3), but it calls popen(), #undef HAVE_GETCWD so
311- the replacement in getcwd.c will be built. */
312-#if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN)
313+/* If we have a getcwd(3), but one that does not dynamically allocate memory,
314+ #undef HAVE_GETCWD so the replacement in getcwd.c will be built. We do
315+ not do this on Solaris, because their implementation of loopback mounts
316+ breaks the traditional file system assumptions that getcwd uses. */
317+#if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN) && !defined (SOLARIS)
318 # undef HAVE_GETCWD
319 #endif
320
321diff -Naur bash-3.2.orig/config.h.in bash-3.2/config.h.in
[5cd07a2]322--- bash-3.2.orig/config.h.in 2006-09-12 13:00:54.000000000 -0700
323+++ bash-3.2/config.h.in 2007-09-03 21:59:23.000000000 -0700
[24cc73c]324@@ -1,6 +1,6 @@
325 /* config.h -- Configuration file for bash. */
326
327-/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
328+/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
329
330 This file is part of GNU Bash, the Bourne Again SHell.
331
332@@ -413,6 +413,8 @@
333
334 #undef HAVE_DECL_STRTOLD
335
336+#undef PRI_MACROS_BROKEN
337+
338 #undef STRTOLD_BROKEN
339
340 /* Define if WCONTINUED is defined in system headers, but rejected by waitpid */
341@@ -1006,6 +1008,9 @@
342 /* Define if you have the `dcgettext' function. */
343 #undef HAVE_DCGETTEXT
344
345+/* Define if you have the `localeconv' function. */
346+#undef HAVE_LOCALECONV
347+
348 /* Define if your system has a working `malloc' function. */
349 /* #undef HAVE_MALLOC */
350
351diff -Naur bash-3.2.orig/configure bash-3.2/configure
[5cd07a2]352--- bash-3.2.orig/configure 2006-09-26 08:06:01.000000000 -0700
353+++ bash-3.2/configure 2007-09-03 21:59:22.000000000 -0700
[24cc73c]354@@ -27316,7 +27316,8 @@
355 sco3.2v4*) LOCAL_CFLAGS="-DMUST_UNBLOCK_CHLD -DPATH_MAX=1024" ;;
356 sco3.2*) LOCAL_CFLAGS=-DMUST_UNBLOCK_CHLD ;;
357 sunos4*) LOCAL_CFLAGS=-DSunOS4 ;;
358-solaris2.5*) LOCAL_CFLAGS=-DSunOS5 ;;
359+solaris2.5*) LOCAL_CFLAGS="-DSunOS5 -DSOLARIS" ;;
360+solaris2*) LOCAL_CFLAGS=-DSOLARIS ;;
361 lynxos*) LOCAL_CFLAGS=-DRECYCLES_PIDS ;;
362 linux*) LOCAL_LDFLAGS=-rdynamic # allow dynamic loading
363 case "`uname -r`" in
364diff -Naur bash-3.2.orig/configure.in bash-3.2/configure.in
[5cd07a2]365--- bash-3.2.orig/configure.in 2006-09-26 08:05:45.000000000 -0700
366+++ bash-3.2/configure.in 2007-09-03 21:59:22.000000000 -0700
[24cc73c]367@@ -5,7 +5,7 @@
368 dnl
369 dnl Process this file with autoconf to produce a configure script.
370
371-# Copyright (C) 1987-2006 Free Software Foundation, Inc.
372+# Copyright (C) 1987-2007 Free Software Foundation, Inc.
373
374 # This program is free software; you can redistribute it and/or modify
375 # it under the terms of the GNU General Public License as published by
376@@ -991,7 +991,8 @@
377 sco3.2v4*) LOCAL_CFLAGS="-DMUST_UNBLOCK_CHLD -DPATH_MAX=1024" ;;
378 sco3.2*) LOCAL_CFLAGS=-DMUST_UNBLOCK_CHLD ;;
379 sunos4*) LOCAL_CFLAGS=-DSunOS4 ;;
380-solaris2.5*) LOCAL_CFLAGS=-DSunOS5 ;;
381+solaris2.5*) LOCAL_CFLAGS="-DSunOS5 -DSOLARIS" ;;
382+solaris2*) LOCAL_CFLAGS=-DSOLARIS ;;
383 lynxos*) LOCAL_CFLAGS=-DRECYCLES_PIDS ;;
384 linux*) LOCAL_LDFLAGS=-rdynamic # allow dynamic loading
385 case "`uname -r`" in
386diff -Naur bash-3.2.orig/execute_cmd.c bash-3.2/execute_cmd.c
[5cd07a2]387--- bash-3.2.orig/execute_cmd.c 2006-08-25 21:23:17.000000000 -0700
388+++ bash-3.2/execute_cmd.c 2007-09-03 21:59:26.000000000 -0700
[24cc73c]389@@ -1,6 +1,6 @@
390 /* execute_cmd.c -- Execute a COMMAND structure. */
391
392-/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
393+/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
394
395 This file is part of GNU Bash, the Bourne Again SHell.
396
397@@ -2546,7 +2546,7 @@
398 arg1 = cond_expand_word (cond->left->op, 0);
399 if (arg1 == 0)
400 arg1 = nullstr;
401- arg2 = cond_expand_word (cond->right->op, patmatch||rmatch);
402+ arg2 = cond_expand_word (cond->right->op, rmatch ? 2 : (patmatch ? 1 : 0));
403 if (arg2 == 0)
404 arg2 = nullstr;
405
406@@ -3050,6 +3050,11 @@
407 if (command_line == 0)
408 command_line = savestring (the_printed_command_except_trap);
409
410+#if defined (PROCESS_SUBSTITUTION)
411+ if ((subshell_environment & SUBSHELL_COMSUB) && (simple_command->flags & CMD_NO_FORK) && fifos_pending() > 0)
412+ simple_command->flags &= ~CMD_NO_FORK;
413+#endif
414+
415 execute_disk_command (words, simple_command->redirects, command_line,
416 pipe_in, pipe_out, async, fds_to_close,
417 simple_command->flags);
[5cd07a2]418diff -Naur bash-3.2.orig/expr.c bash-3.2/expr.c
419--- bash-3.2.orig/expr.c 2005-12-28 14:47:03.000000000 -0800
420+++ bash-3.2/expr.c 2007-09-03 21:59:34.000000000 -0700
421@@ -929,6 +929,7 @@
422 if (interactive_shell)
423 {
424 expr_unwind ();
425+ top_level_cleanup ();
426 jump_to_top_level (DISCARD);
427 }
428 else
[24cc73c]429diff -Naur bash-3.2.orig/findcmd.c bash-3.2/findcmd.c
[5cd07a2]430--- bash-3.2.orig/findcmd.c 2005-08-17 13:49:54.000000000 -0700
431+++ bash-3.2/findcmd.c 2007-09-03 21:59:18.000000000 -0700
[24cc73c]432@@ -308,7 +308,7 @@
433 if (hashed_file && (posixly_correct || check_hashed_filenames))
434 {
435 st = file_status (hashed_file);
436- if ((st ^ (FS_EXISTS | FS_EXECABLE)) != 0)
437+ if ((st & (FS_EXISTS|FS_EXECABLE)) != (FS_EXISTS|FS_EXECABLE))
438 {
439 phash_remove (pathname);
440 free (hashed_file);
441diff -Naur bash-3.2.orig/jobs.c bash-3.2/jobs.c
[5cd07a2]442--- bash-3.2.orig/jobs.c 2006-07-29 13:40:48.000000000 -0700
443+++ bash-3.2/jobs.c 2007-09-03 21:59:30.000000000 -0700
444@@ -783,11 +783,13 @@
445 if (jobs[js.j_firstj] == 0)
446 {
447 old = js.j_firstj++;
448+ if (old >= js.j_jobslots)
449+ old = js.j_jobslots - 1;
450 while (js.j_firstj != old)
451 {
452 if (js.j_firstj >= js.j_jobslots)
453 js.j_firstj = 0;
454- if (jobs[js.j_firstj])
455+ if (jobs[js.j_firstj] || js.j_firstj == old) /* needed if old == 0 */
456 break;
457 js.j_firstj++;
458 }
459@@ -797,11 +799,13 @@
460 if (jobs[js.j_lastj] == 0)
461 {
462 old = js.j_lastj--;
463+ if (old < 0)
464+ old = 0;
465 while (js.j_lastj != old)
466 {
467 if (js.j_lastj < 0)
468 js.j_lastj = js.j_jobslots - 1;
469- if (jobs[js.j_lastj])
470+ if (jobs[js.j_lastj] || js.j_lastj == old) /* needed if old == js.j_jobslots */
471 break;
472 js.j_lastj--;
473 }
474@@ -963,7 +967,11 @@
475 reap_dead_jobs ();
476 realloc_jobs_list ();
477
478- return (js.j_lastj);
479+#ifdef DEBUG
480+ itrace("compact_jobs_list: returning %d", (js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
481+#endif
482+
483+ return ((js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
484 }
485
486 /* Delete the job at INDEX from the job list. Must be called
487@@ -984,8 +992,6 @@
[24cc73c]488 temp = jobs[job_index];
489 if (temp == 0)
490 return;
491- if (job_index == js.j_current || job_index == js.j_previous)
492- reset_current ();
493
494 if ((dflags & DEL_NOBGPID) == 0)
495 {
[5cd07a2]496@@ -1028,6 +1034,9 @@
[24cc73c]497 js.j_firstj = js.j_lastj = 0;
498 else if (jobs[js.j_firstj] == 0 || jobs[js.j_lastj] == 0)
499 reset_job_indices ();
500+
501+ if (job_index == js.j_current || job_index == js.j_previous)
502+ reset_current ();
503 }
504
505 /* Must be called with SIGCHLD blocked. */
[5cd07a2]506diff -Naur bash-3.2.orig/lib/readline/complete.c bash-3.2/lib/readline/complete.c
507--- bash-3.2.orig/lib/readline/complete.c 2006-07-28 08:35:49.000000000 -0700
508+++ bash-3.2/lib/readline/complete.c 2007-09-03 21:59:32.000000000 -0700
509@@ -428,7 +428,7 @@
510 return (1);
511 if (c == 'n' || c == 'N' || c == RUBOUT)
512 return (0);
513- if (c == ABORT_CHAR)
514+ if (c == ABORT_CHAR || c < 0)
515 _rl_abort_internal ();
516 if (for_pager && (c == NEWLINE || c == RETURN))
517 return (2);
[24cc73c]518diff -Naur bash-3.2.orig/lib/readline/display.c bash-3.2/lib/readline/display.c
[5cd07a2]519--- bash-3.2.orig/lib/readline/display.c 2006-09-14 11:20:12.000000000 -0700
520+++ bash-3.2/lib/readline/display.c 2007-09-03 21:59:40.000000000 -0700
[24cc73c]521@@ -561,6 +561,17 @@
522 wrap_offset = prompt_invis_chars_first_line = 0;
523 }
524
525+#if defined (HANDLE_MULTIBYTE)
526+#define CHECK_INV_LBREAKS() \
527+ do { \
528+ if (newlines >= (inv_lbsize - 2)) \
529+ { \
530+ inv_lbsize *= 2; \
531+ inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
532+ _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \
533+ } \
534+ } while (0)
535+#else
536 #define CHECK_INV_LBREAKS() \
537 do { \
538 if (newlines >= (inv_lbsize - 2)) \
539@@ -569,6 +580,7 @@
540 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
541 } \
542 } while (0)
543+#endif /* HANDLE_MULTIBYTE */
544
545 #if defined (HANDLE_MULTIBYTE)
546 #define CHECK_LPOS() \
[5cd07a2]547@@ -1506,11 +1518,31 @@
548 {
549 /* Non-zero if we're increasing the number of lines. */
550 int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
551+ /* If col_lendiff is > 0, implying that the new string takes up more
552+ screen real estate than the old, but lendiff is < 0, meaning that it
553+ takes fewer bytes, we need to just output the characters starting
554+ from the first difference. These will overwrite what is on the
555+ display, so there's no reason to do a smart update. This can really
556+ only happen in a multibyte environment. */
557+ if (lendiff < 0)
558+ {
559+ _rl_output_some_chars (nfd, temp);
560+ _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
561+ /* If nfd begins before any invisible characters in the prompt,
562+ adjust _rl_last_c_pos to account for wrap_offset and set
563+ cpos_adjusted to let the caller know. */
564+ if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
565+ {
566+ _rl_last_c_pos -= wrap_offset;
567+ cpos_adjusted = 1;
568+ }
569+ return;
570+ }
571 /* Sometimes it is cheaper to print the characters rather than
572 use the terminal's capabilities. If we're growing the number
573 of lines, make sure we actually cause the new line to wrap
574 around on auto-wrapping terminals. */
575- if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
576+ else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
577 {
578 /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
579 _rl_horizontal_scroll_mode == 1, inserting the characters with
580@@ -1586,8 +1618,22 @@
[24cc73c]581 temp = nls - nfd;
582 if (temp > 0)
583 {
584+ /* If nfd begins at the prompt, or before the invisible
585+ characters in the prompt, we need to adjust _rl_last_c_pos
586+ in a multibyte locale to account for the wrap offset and
587+ set cpos_adjusted accordingly. */
588 _rl_output_some_chars (nfd, temp);
589- _rl_last_c_pos += _rl_col_width (nfd, 0, temp);;
590+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
591+ {
592+ _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
593+ if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
594+ {
595+ _rl_last_c_pos -= wrap_offset;
596+ cpos_adjusted = 1;
597+ }
598+ }
599+ else
600+ _rl_last_c_pos += temp;
601 }
602 }
603 /* Otherwise, print over the existing material. */
[5cd07a2]604@@ -1595,8 +1641,20 @@
[24cc73c]605 {
606 if (temp > 0)
607 {
608+ /* If nfd begins at the prompt, or before the invisible
609+ characters in the prompt, we need to adjust _rl_last_c_pos
610+ in a multibyte locale to account for the wrap offset and
611+ set cpos_adjusted accordingly. */
612 _rl_output_some_chars (nfd, temp);
613 _rl_last_c_pos += col_temp; /* XXX */
614+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
615+ {
616+ if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
617+ {
618+ _rl_last_c_pos -= wrap_offset;
619+ cpos_adjusted = 1;
620+ }
621+ }
622 }
623 lendiff = (oe - old) - (ne - new);
624 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
[5cd07a2]625@@ -1732,7 +1790,10 @@
[24cc73c]626 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
627 {
628 dpos = _rl_col_width (data, 0, new);
629- if (dpos > prompt_last_invisible) /* XXX - don't use woff here */
630+ /* Use NEW when comparing against the last invisible character in the
631+ prompt string, since they're both buffer indices and DPOS is a
632+ desired display position. */
633+ if (new > prompt_last_invisible) /* XXX - don't use woff here */
634 {
635 dpos -= woff;
636 /* Since this will be assigned to _rl_last_c_pos at the end (more
[5cd07a2]637@@ -2380,6 +2441,8 @@
[24cc73c]638
639 if (end <= start)
640 return 0;
641+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
642+ return (end - start);
643
644 memset (&ps, 0, sizeof (mbstate_t));
645
[5cd07a2]646diff -Naur bash-3.2.orig/lib/readline/input.c bash-3.2/lib/readline/input.c
647--- bash-3.2.orig/lib/readline/input.c 2006-08-16 12:15:16.000000000 -0700
648+++ bash-3.2/lib/readline/input.c 2007-09-03 21:59:42.000000000 -0700
649@@ -133,8 +133,11 @@
650 return (0);
651
652 *key = ibuffer[pop_index++];
653-
654+#if 0
655 if (pop_index >= ibuffer_len)
656+#else
657+ if (pop_index > ibuffer_len)
658+#endif
659 pop_index = 0;
660
661 return (1);
662@@ -250,7 +253,8 @@
663 while (chars_avail--)
664 {
665 k = (*rl_getc_function) (rl_instream);
666- rl_stuff_char (k);
667+ if (rl_stuff_char (k) == 0)
668+ break; /* some problem; no more room */
669 if (k == NEWLINE || k == RETURN)
670 break;
671 }
672@@ -373,7 +377,11 @@
673 RL_SETSTATE (RL_STATE_INPUTPENDING);
674 }
675 ibuffer[push_index++] = key;
676+#if 0
677 if (push_index >= ibuffer_len)
678+#else
679+ if (push_index > ibuffer_len)
680+#endif
681 push_index = 0;
682
683 return 1;
684@@ -513,20 +521,26 @@
685 char *mbchar;
686 int size;
687 {
688- int mb_len = 0;
689+ int mb_len, c;
690 size_t mbchar_bytes_length;
691 wchar_t wc;
692 mbstate_t ps, ps_back;
693
694 memset(&ps, 0, sizeof (mbstate_t));
695 memset(&ps_back, 0, sizeof (mbstate_t));
696-
697+
698+ mb_len = 0;
699 while (mb_len < size)
700 {
701 RL_SETSTATE(RL_STATE_MOREINPUT);
702- mbchar[mb_len++] = rl_read_key ();
703+ c = rl_read_key ();
704 RL_UNSETSTATE(RL_STATE_MOREINPUT);
705
706+ if (c < 0)
707+ break;
708+
709+ mbchar[mb_len++] = c;
710+
711 mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps);
712 if (mbchar_bytes_length == (size_t)(-1))
713 break; /* invalid byte sequence for the current locale */
714@@ -564,7 +578,7 @@
715
716 c = first;
717 memset (mb, 0, mlen);
718- for (i = 0; i < mlen; i++)
719+ for (i = 0; c >= 0 && i < mlen; i++)
720 {
721 mb[i] = (char)c;
722 memset (&ps, 0, sizeof (mbstate_t));
723diff -Naur bash-3.2.orig/lib/readline/isearch.c bash-3.2/lib/readline/isearch.c
724--- bash-3.2.orig/lib/readline/isearch.c 2005-12-26 14:18:53.000000000 -0800
725+++ bash-3.2/lib/readline/isearch.c 2007-09-03 21:59:32.000000000 -0700
726@@ -327,8 +327,15 @@
727 rl_command_func_t *f;
728
729 f = (rl_command_func_t *)NULL;
730-
731- /* Translate the keys we do something with to opcodes. */
732+
733+ if (c < 0)
734+ {
735+ cxt->sflags |= SF_FAILED;
736+ cxt->history_pos = cxt->last_found_line;
737+ return -1;
738+ }
739+
740+ /* Translate the keys we do something with to opcodes. */
741 if (c >= 0 && _rl_keymap[c].type == ISFUNC)
742 {
743 f = _rl_keymap[c].function;
744diff -Naur bash-3.2.orig/lib/readline/misc.c bash-3.2/lib/readline/misc.c
745--- bash-3.2.orig/lib/readline/misc.c 2005-12-26 14:20:46.000000000 -0800
746+++ bash-3.2/lib/readline/misc.c 2007-09-03 21:59:32.000000000 -0700
747@@ -146,6 +146,8 @@
748 rl_restore_prompt ();
749 rl_clear_message ();
750 RL_UNSETSTATE(RL_STATE_NUMERICARG);
751+ if (key < 0)
752+ return -1;
753 return (_rl_dispatch (key, _rl_keymap));
754 }
755 }
756diff -Naur bash-3.2.orig/lib/readline/readline.c bash-3.2/lib/readline/readline.c
757--- bash-3.2.orig/lib/readline/readline.c 2006-08-16 12:00:36.000000000 -0700
758+++ bash-3.2/lib/readline/readline.c 2007-09-03 21:59:32.000000000 -0700
759@@ -645,6 +645,11 @@
760 if ((cxt->flags & KSEQ_DISPATCHED) == 0)
761 {
762 nkey = _rl_subseq_getchar (cxt->okey);
763+ if (nkey < 0)
764+ {
765+ _rl_abort_internal ();
766+ return -1;
767+ }
768 r = _rl_dispatch_subseq (nkey, cxt->dmap, cxt->subseq_arg);
769 cxt->flags |= KSEQ_DISPATCHED;
770 }
771diff -Naur bash-3.2.orig/lib/readline/text.c bash-3.2/lib/readline/text.c
772--- bash-3.2.orig/lib/readline/text.c 2006-07-28 08:55:27.000000000 -0700
773+++ bash-3.2/lib/readline/text.c 2007-09-03 21:59:32.000000000 -0700
774@@ -857,6 +857,9 @@
775 c = rl_read_key ();
776 RL_UNSETSTATE(RL_STATE_MOREINPUT);
777
778+ if (c < 0)
779+ return -1;
780+
781 #if defined (HANDLE_SIGNALS)
782 if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
783 _rl_restore_tty_signals ();
784@@ -1520,6 +1523,9 @@
785
786 mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
787
788+ if (mb_len <= 0)
789+ return -1;
790+
791 if (count < 0)
792 return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
793 else
794@@ -1536,6 +1542,9 @@
795 c = rl_read_key ();
796 RL_UNSETSTATE(RL_STATE_MOREINPUT);
797
798+ if (c < 0)
799+ return -1;
800+
801 if (count < 0)
802 return (_rl_char_search_internal (-count, bdir, c));
803 else
804diff -Naur bash-3.2.orig/lib/readline/vi_mode.c bash-3.2/lib/readline/vi_mode.c
805--- bash-3.2.orig/lib/readline/vi_mode.c 2006-07-29 13:42:28.000000000 -0700
806+++ bash-3.2/lib/readline/vi_mode.c 2007-09-03 21:59:32.000000000 -0700
807@@ -886,6 +886,13 @@
808 RL_SETSTATE(RL_STATE_MOREINPUT);
809 c = rl_read_key ();
810 RL_UNSETSTATE(RL_STATE_MOREINPUT);
811+
812+ if (c < 0)
813+ {
814+ *nextkey = 0;
815+ return -1;
816+ }
817+
818 *nextkey = c;
819
820 if (!member (c, vi_motion))
821@@ -902,6 +909,11 @@
822 RL_SETSTATE(RL_STATE_MOREINPUT);
823 c = rl_read_key (); /* real command */
824 RL_UNSETSTATE(RL_STATE_MOREINPUT);
825+ if (c < 0)
826+ {
827+ *nextkey = 0;
828+ return -1;
829+ }
830 *nextkey = c;
831 }
832 else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
833@@ -1224,14 +1236,22 @@
834 _rl_vi_callback_char_search (data)
835 _rl_callback_generic_arg *data;
836 {
837+ int c;
838 #if defined (HANDLE_MULTIBYTE)
839- _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
840+ c = _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
841 #else
842 RL_SETSTATE(RL_STATE_MOREINPUT);
843- _rl_vi_last_search_char = rl_read_key ();
844+ c = rl_read_key ();
845 RL_UNSETSTATE(RL_STATE_MOREINPUT);
846 #endif
847
848+ if (c <= 0)
849+ return -1;
850+
851+#if !defined (HANDLE_MULTIBYTE)
852+ _rl_vi_last_search_char = c;
853+#endif
854+
855 _rl_callback_func = 0;
856 _rl_want_redisplay = 1;
857
858@@ -1247,6 +1267,7 @@
859 rl_vi_char_search (count, key)
860 int count, key;
861 {
862+ int c;
863 #if defined (HANDLE_MULTIBYTE)
864 static char *target;
865 static int tlen;
866@@ -1293,11 +1314,17 @@
867 else
868 {
869 #if defined (HANDLE_MULTIBYTE)
870- _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
871+ c = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
872+ if (c <= 0)
873+ return -1;
874+ _rl_vi_last_search_mblen = c;
875 #else
876 RL_SETSTATE(RL_STATE_MOREINPUT);
877- _rl_vi_last_search_char = rl_read_key ();
878+ c = rl_read_key ();
879 RL_UNSETSTATE(RL_STATE_MOREINPUT);
880+ if (c < 0)
881+ return -1;
882+ _rl_vi_last_search_char = c;
883 #endif
884 }
885 }
886@@ -1467,6 +1494,9 @@
887 c = rl_read_key ();
888 RL_UNSETSTATE(RL_STATE_MOREINPUT);
889
890+ if (c < 0)
891+ return -1;
892+
893 #if defined (HANDLE_MULTIBYTE)
894 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
895 c = _rl_read_mbstring (c, mb, mlen);
896@@ -1485,6 +1515,9 @@
897
898 _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
899
900+ if (c < 0)
901+ return -1;
902+
903 _rl_callback_func = 0;
904 _rl_want_redisplay = 1;
905
906@@ -1516,6 +1549,9 @@
907 else
908 _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
909
910+ if (c < 0)
911+ return -1;
912+
913 return (_rl_vi_change_char (count, c, mb));
914 }
915
916@@ -1650,7 +1686,7 @@
917 ch = rl_read_key ();
918 RL_UNSETSTATE(RL_STATE_MOREINPUT);
919
920- if (ch < 'a' || ch > 'z')
921+ if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */
922 {
923 rl_ding ();
924 return -1;
925@@ -1702,7 +1738,7 @@
926 rl_point = rl_mark;
927 return 0;
928 }
929- else if (ch < 'a' || ch > 'z')
930+ else if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */
931 {
932 rl_ding ();
933 return -1;
[24cc73c]934diff -Naur bash-3.2.orig/lib/sh/snprintf.c bash-3.2/lib/sh/snprintf.c
[5cd07a2]935--- bash-3.2.orig/lib/sh/snprintf.c 2006-04-06 06:48:40.000000000 -0700
936+++ bash-3.2/lib/sh/snprintf.c 2007-09-03 21:59:19.000000000 -0700
[24cc73c]937@@ -471,6 +471,8 @@
938 10^x ~= r
939 * log_10(200) = 2;
940 * log_10(250) = 2;
941+ *
942+ * NOTE: do not call this with r == 0 -- an infinite loop results.
943 */
944 static int
945 log_10(r)
946@@ -576,8 +578,11 @@
947 {
948 integral_part[0] = '0';
949 integral_part[1] = '\0';
950- fraction_part[0] = '0';
951- fraction_part[1] = '\0';
952+ /* The fractional part has to take the precision into account */
953+ for (ch = 0; ch < precision-1; ch++)
954+ fraction_part[ch] = '0';
955+ fraction_part[ch] = '0';
956+ fraction_part[ch+1] = '\0';
957 if (fract)
958 *fract = fraction_part;
959 return integral_part;
960@@ -663,7 +668,8 @@
961 p->flags &= ~PF_ZEROPAD;
962
963 sd = d; /* signed for ' ' padding in base 10 */
964- flags = (*p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
965+ flags = 0;
966+ flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
967 if (*p->pf == 'X')
968 flags |= FL_HEXUPPER;
969
970@@ -733,7 +739,7 @@
971 p->flags &= ~PF_ZEROPAD;
972
973 sd = d; /* signed for ' ' padding in base 10 */
974- flags = (*p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
975+ flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
976 if (*p->pf == 'X')
977 flags |= FL_HEXUPPER;
978
979@@ -805,6 +811,7 @@
980 PUT_CHAR(*tmp, p);
981 tmp++;
982 }
983+
984 PAD_LEFT(p);
985 }
986
987@@ -972,11 +979,21 @@
988 if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp)))
989 tmp = t;
990
991+ if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
992+ {
993+ /* smash the trailing zeros unless altform */
994+ for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
995+ tmp2[i] = '\0';
996+ if (tmp2[0] == '\0')
997+ p->precision = 0;
998+ }
999+
1000 /* calculate the padding. 1 for the dot */
1001 p->width = p->width -
1002 ((d > 0. && p->justify == RIGHT) ? 1:0) -
1003 ((p->flags & PF_SPACE) ? 1:0) -
1004- strlen(tmp) - p->precision - 1;
1005+ strlen(tmp) - p->precision -
1006+ ((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0); /* radix char */
1007 PAD_RIGHT(p);
1008 PUT_PLUS(d, p, 0.);
1009 PUT_SPACE(d, p, 0.);
1010@@ -991,11 +1008,6 @@
1011 if (p->precision != 0 || (p->flags & PF_ALTFORM))
1012 PUT_CHAR(decpoint, p); /* put the '.' */
1013
1014- if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
1015- /* smash the trailing zeros unless altform */
1016- for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
1017- tmp2[i] = '\0';
1018-
1019 for (; *tmp2; tmp2++)
1020 PUT_CHAR(*tmp2, p); /* the fraction */
1021
1022@@ -1011,14 +1023,19 @@
1023 char *tmp, *tmp2;
1024 int j, i;
1025
1026- if (chkinfnan(p, d, 1) || chkinfnan(p, d, 2))
1027+ if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2)))
1028 return; /* already printed nan or inf */
1029
1030 GETLOCALEDATA(decpoint, thoussep, grouping);
1031 DEF_PREC(p);
1032- j = log_10(d);
1033- d = d / pow_10(j); /* get the Mantissa */
1034- d = ROUND(d, p);
1035+ if (d == 0.)
1036+ j = 0;
1037+ else
1038+ {
1039+ j = log_10(d);
1040+ d = d / pow_10(j); /* get the Mantissa */
1041+ d = ROUND(d, p);
1042+ }
1043 tmp = dtoa(d, p->precision, &tmp2);
1044
1045 /* 1 for unit, 1 for the '.', 1 for 'e|E',
1046@@ -1076,6 +1093,7 @@
1047 PUT_CHAR(*tmp, p);
1048 tmp++;
1049 }
1050+
1051 PAD_LEFT(p);
1052 }
1053 #endif
1054@@ -1358,7 +1376,7 @@
1055 STAR_ARGS(data);
1056 DEF_PREC(data);
1057 d = GETDOUBLE(data);
1058- i = log_10(d);
1059+ i = (d != 0.) ? log_10(d) : -1;
1060 /*
1061 * for '%g|%G' ANSI: use f if exponent
1062 * is in the range or [-4,p] exclusively
1063diff -Naur bash-3.2.orig/parse.y bash-3.2/parse.y
[5cd07a2]1064--- bash-3.2.orig/parse.y 2006-09-19 13:37:21.000000000 -0700
1065+++ bash-3.2/parse.y 2007-09-03 21:59:35.000000000 -0700
[24cc73c]1066@@ -1029,6 +1029,7 @@
1067 #define PST_CMDTOKEN 0x1000 /* command token OK - unused */
1068 #define PST_COMPASSIGN 0x2000 /* parsing x=(...) compound assignment */
1069 #define PST_ASSIGNOK 0x4000 /* assignment statement ok in this context */
1070+#define PST_REGEXP 0x8000 /* parsing an ERE/BRE as a single word */
1071
1072 /* Initial size to allocate for tokens, and the
1073 amount to grow them by. */
1074@@ -2591,6 +2592,9 @@
1075 return (character);
1076 }
1077
1078+ if (parser_state & PST_REGEXP)
1079+ goto tokword;
1080+
1081 /* Shell meta-characters. */
1082 if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
1083 {
1084@@ -2698,6 +2702,7 @@
1085 if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
1086 return (character);
1087
1088+tokword:
1089 /* Okay, if we got this far, we have to read a word. Read one,
1090 and then check it against the known ones. */
1091 result = read_token_word (character);
1092@@ -2735,7 +2740,7 @@
1093 /* itrace("parse_matched_pair: open = %c close = %c", open, close); */
1094 count = 1;
1095 pass_next_character = backq_backslash = was_dollar = in_comment = 0;
1096- check_comment = (flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0;
1097+ check_comment = (flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0;
1098
1099 /* RFLAGS is the set of flags we want to pass to recursive calls. */
1100 rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
1101@@ -3202,8 +3207,11 @@
1102 if (tok == WORD && test_binop (yylval.word->word))
1103 op = yylval.word;
1104 #if defined (COND_REGEXP)
1105- else if (tok == WORD && STREQ (yylval.word->word,"=~"))
1106- op = yylval.word;
1107+ else if (tok == WORD && STREQ (yylval.word->word, "=~"))
1108+ {
1109+ op = yylval.word;
1110+ parser_state |= PST_REGEXP;
1111+ }
1112 #endif
1113 else if (tok == '<' || tok == '>')
1114 op = make_word_from_token (tok); /* ( */
1115@@ -3234,6 +3242,7 @@
1116
1117 /* rhs */
1118 tok = read_token (READ);
1119+ parser_state &= ~PST_REGEXP;
1120 if (tok == WORD)
1121 {
1122 tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
[5cd07a2]1123@@ -3367,7 +3376,7 @@
1124 if (pass_next_character)
1125 {
1126 pass_next_character = 0;
1127- goto got_character;
1128+ goto got_escaped_character;
1129 }
1130
1131 cd = current_delimiter (dstack);
[24cc73c]1132@@ -3419,9 +3428,34 @@
1133 goto next_character;
1134 }
1135
1136+#ifdef COND_REGEXP
1137+ /* When parsing a regexp as a single word inside a conditional command,
1138+ we need to special-case characters special to both the shell and
1139+ regular expressions. Right now, that is only '(' and '|'. */ /*)*/
1140+ if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|')) /*)*/
1141+ {
1142+ if (character == '|')
1143+ goto got_character;
1144+
1145+ push_delimiter (dstack, character);
1146+ ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
1147+ pop_delimiter (dstack);
1148+ if (ttok == &matched_pair_error)
1149+ return -1; /* Bail immediately. */
1150+ RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
1151+ token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
1152+ token[token_index++] = character;
1153+ strcpy (token + token_index, ttok);
1154+ token_index += ttoklen;
1155+ FREE (ttok);
1156+ dollar_present = all_digit_token = 0;
1157+ goto next_character;
1158+ }
1159+#endif /* COND_REGEXP */
1160+
1161 #ifdef EXTENDED_GLOB
1162 /* Parse a ksh-style extended pattern matching specification. */
1163- if (extended_glob && PATTERN_CHAR (character))
1164+ if MBTEST(extended_glob && PATTERN_CHAR (character))
1165 {
1166 peek_char = shell_getc (1);
1167 if MBTEST(peek_char == '(') /* ) */
[5cd07a2]1168@@ -3616,12 +3650,14 @@
1169
1170 got_character:
1171
1172- all_digit_token &= DIGIT (character);
1173- dollar_present |= character == '$';
1174-
1175 if (character == CTLESC || character == CTLNUL)
1176 token[token_index++] = CTLESC;
1177
1178+ got_escaped_character:
1179+
1180+ all_digit_token &= DIGIT (character);
1181+ dollar_present |= character == '$';
1182+
1183 token[token_index++] = character;
1184
1185 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
[24cc73c]1186diff -Naur bash-3.2.orig/patchlevel.h bash-3.2/patchlevel.h
[5cd07a2]1187--- bash-3.2.orig/patchlevel.h 2006-04-13 05:31:04.000000000 -0700
1188+++ bash-3.2/patchlevel.h 2007-09-03 21:59:42.000000000 -0700
[24cc73c]1189@@ -25,6 +25,6 @@
1190 regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
1191 looks for to find the patch level (for the sccs version string). */
1192
1193-#define PATCHLEVEL 0
[5cd07a2]1194+#define PATCHLEVEL 25
[24cc73c]1195
1196 #endif /* _PATCHLEVEL_H_ */
1197diff -Naur bash-3.2.orig/pathexp.c bash-3.2/pathexp.c
[5cd07a2]1198--- bash-3.2.orig/pathexp.c 2002-05-06 10:43:05.000000000 -0700
1199+++ bash-3.2/pathexp.c 2007-09-03 21:59:21.000000000 -0700
[24cc73c]1200@@ -1,6 +1,6 @@
1201 /* pathexp.c -- The shell interface to the globbing library. */
1202
1203-/* Copyright (C) 1995-2002 Free Software Foundation, Inc.
1204+/* Copyright (C) 1995-2007 Free Software Foundation, Inc.
1205
1206 This file is part of GNU Bash, the Bourne Again SHell.
1207
1208@@ -110,6 +110,33 @@
1209 return (0);
1210 }
1211
1212+/* Return 1 if C is a character that is `special' in a POSIX ERE and needs to
1213+ be quoted to match itself. */
1214+static inline int
1215+ere_char (c)
1216+ int c;
1217+{
1218+ switch (c)
1219+ {
1220+ case '.':
1221+ case '[':
1222+ case '\\':
1223+ case '(':
1224+ case ')':
1225+ case '*':
1226+ case '+':
1227+ case '?':
1228+ case '{':
1229+ case '|':
1230+ case '^':
1231+ case '$':
1232+ return 1;
1233+ default:
1234+ return 0;
1235+ }
1236+ return (0);
1237+}
1238+
1239 /* PATHNAME can contain characters prefixed by CTLESC; this indicates
1240 that the character is to be quoted. We quote it here in the style
1241 that the glob library recognizes. If flags includes QGLOB_CVTNULL,
1242@@ -142,6 +169,8 @@
1243 {
1244 if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/')
1245 continue;
1246+ if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
1247+ continue;
1248 temp[j++] = '\\';
1249 i++;
1250 if (pathname[i] == '\0')
1251diff -Naur bash-3.2.orig/pathexp.h bash-3.2/pathexp.h
[5cd07a2]1252--- bash-3.2.orig/pathexp.h 2005-02-19 14:23:18.000000000 -0800
1253+++ bash-3.2/pathexp.h 2007-09-03 21:59:21.000000000 -0700
[24cc73c]1254@@ -1,6 +1,6 @@
1255 /* pathexp.h -- The shell interface to the globbing library. */
1256
1257-/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
1258+/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
1259
1260 This file is part of GNU Bash, the Bourne Again SHell.
1261
1262@@ -32,6 +32,7 @@
1263 /* Flag values for quote_string_for_globbing */
1264 #define QGLOB_CVTNULL 0x01 /* convert QUOTED_NULL strings to '\0' */
1265 #define QGLOB_FILENAME 0x02 /* do correct quoting for matching filenames */
1266+#define QGLOB_REGEXP 0x04 /* quote an ERE for regcomp/regexec */
1267
1268 #if defined (EXTENDED_GLOB)
1269 /* Flags to OR with other flag args to strmatch() to enabled the extended
1270diff -Naur bash-3.2.orig/po/ru.po bash-3.2/po/ru.po
[5cd07a2]1271--- bash-3.2.orig/po/ru.po 2006-01-10 14:51:03.000000000 -0800
1272+++ bash-3.2/po/ru.po 2007-09-03 21:59:10.000000000 -0700
[24cc73c]1273@@ -12,7 +12,7 @@
1274 "Last-Translator: Evgeniy Dushistov <dushistov@mail.ru>\n"
1275 "Language-Team: Russian <ru@li.org>\n"
1276 "MIME-Version: 1.0\n"
1277-"Content-Type: text/plain; charset=UTF-8\n"
1278+"Content-Type: text/plain; charset=KOI8-R\n"
1279 "Content-Transfer-Encoding: 8bit\n"
1280 "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
1281
[5cd07a2]1282diff -Naur bash-3.2.orig/sig.c bash-3.2/sig.c
1283--- bash-3.2.orig/sig.c 2006-01-25 11:57:59.000000000 -0800
1284+++ bash-3.2/sig.c 2007-09-03 21:59:34.000000000 -0700
1285@@ -350,6 +350,25 @@
1286 #undef XSIG
1287 #undef XHANDLER
1288
1289+/* Run some of the cleanups that should be performed when we run
1290+ jump_to_top_level from a builtin command context. XXX - might want to
1291+ also call reset_parser here. */
1292+void
1293+top_level_cleanup ()
1294+{
1295+ /* Clean up string parser environment. */
1296+ while (parse_and_execute_level)
1297+ parse_and_execute_cleanup ();
1298+
1299+#if defined (PROCESS_SUBSTITUTION)
1300+ unlink_fifo_list ();
1301+#endif /* PROCESS_SUBSTITUTION */
1302+
1303+ run_unwind_protects ();
1304+ loop_level = continuing = breaking = 0;
1305+ return_catch_flag = 0;
1306+}
1307+
1308 /* What to do when we've been interrupted, and it is safe to handle it. */
1309 void
1310 throw_to_top_level ()
1311diff -Naur bash-3.2.orig/sig.h bash-3.2/sig.h
1312--- bash-3.2.orig/sig.h 2006-01-25 11:50:27.000000000 -0800
1313+++ bash-3.2/sig.h 2007-09-03 21:59:34.000000000 -0700
1314@@ -121,6 +121,7 @@
1315 extern void initialize_signals __P((int));
1316 extern void initialize_terminating_signals __P((void));
1317 extern void reset_terminating_signals __P((void));
1318+extern void top_level_cleanup __P((void));
1319 extern void throw_to_top_level __P((void));
1320 extern void jump_to_top_level __P((int)) __attribute__((__noreturn__));
1321
[24cc73c]1322diff -Naur bash-3.2.orig/subst.c bash-3.2/subst.c
[5cd07a2]1323--- bash-3.2.orig/subst.c 2006-09-19 05:35:09.000000000 -0700
1324+++ bash-3.2/subst.c 2007-09-03 21:59:37.000000000 -0700
[24cc73c]1325@@ -4,7 +4,7 @@
1326 /* ``Have a little faith, there's magic in the night. You ain't a
1327 beauty, but, hey, you're alright.'' */
1328
1329-/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
1330+/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
1331
1332 This file is part of GNU Bash, the Bourne Again SHell.
1333
[5cd07a2]1334@@ -1278,7 +1278,7 @@
1335 {
1336 if (no_longjmp_on_fatal_error == 0)
1337 { /* { */
1338- report_error ("bad substitution: no closing `%s' in %s", "}", string);
1339+ report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
1340 last_command_exit_value = EXECUTION_FAILURE;
1341 exp_jump_to_top_level (DISCARD);
1342 }
[24cc73c]1343@@ -1887,7 +1887,13 @@
1344 sep[1] = '\0';
1345 #endif
1346
1347+ /* XXX -- why call quote_list if ifs == 0? we can get away without doing
1348+ it now that quote_escapes quotes spaces */
1349+#if 0
1350 tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
1351+#else
1352+ tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1353+#endif
1354 ? quote_list (list)
1355 : list_quote_escapes (list);
1356
1357@@ -2646,11 +2652,12 @@
1358
1359 /* This needs better error handling. */
1360 /* Expand W for use as an argument to a unary or binary operator in a
1361- [[...]] expression. If SPECIAL is nonzero, this is the rhs argument
1362+ [[...]] expression. If SPECIAL is 1, this is the rhs argument
1363 to the != or == operator, and should be treated as a pattern. In
1364- this case, we quote the string specially for the globbing code. The
1365- caller is responsible for removing the backslashes if the unquoted
1366- words is needed later. */
1367+ this case, we quote the string specially for the globbing code. If
1368+ SPECIAL is 2, this is an rhs argument for the =~ operator, and should
1369+ be quoted appropriately for regcomp/regexec. The caller is responsible
1370+ for removing the backslashes if the unquoted word is needed later. */
1371 char *
1372 cond_expand_word (w, special)
1373 WORD_DESC *w;
1374@@ -2658,6 +2665,7 @@
1375 {
1376 char *r, *p;
1377 WORD_LIST *l;
1378+ int qflags;
1379
1380 if (w->word == 0 || w->word[0] == '\0')
1381 return ((char *)NULL);
1382@@ -2672,8 +2680,11 @@
1383 }
1384 else
1385 {
1386+ qflags = QGLOB_CVTNULL;
1387+ if (special == 2)
1388+ qflags |= QGLOB_REGEXP;
1389 p = string_list (l);
1390- r = quote_string_for_globbing (p, QGLOB_CVTNULL);
1391+ r = quote_string_for_globbing (p, qflags);
1392 free (p);
1393 }
1394 dispose_words (l);
1395@@ -2916,7 +2927,12 @@
1396
1397 /* Quote escape characters in string s, but no other characters. This is
1398 used to protect CTLESC and CTLNUL in variable values from the rest of
1399- the word expansion process after the variable is expanded. */
1400+ the word expansion process after the variable is expanded. If IFS is
1401+ null, we quote spaces as well, just in case we split on spaces later
1402+ (in the case of unquoted $@, we will eventually attempt to split the
1403+ entire word on spaces). Corresponding code exists in dequote_escapes.
1404+ Even if we don't end up splitting on spaces, quoting spaces is not a
1405+ problem. */
1406 char *
1407 quote_escapes (string)
1408 char *string;
1409@@ -2924,17 +2940,19 @@
1410 register char *s, *t;
1411 size_t slen;
1412 char *result, *send;
1413+ int quote_spaces;
1414 DECLARE_MBSTATE;
1415
1416 slen = strlen (string);
1417 send = string + slen;
1418
1419+ quote_spaces = (ifs_value && *ifs_value == 0);
1420 t = result = (char *)xmalloc ((slen * 2) + 1);
1421 s = string;
1422
1423 while (*s)
1424 {
1425- if (*s == CTLESC || *s == CTLNUL)
1426+ if (*s == CTLESC || *s == CTLNUL || (quote_spaces && *s == ' '))
1427 *t++ = CTLESC;
1428 COPY_CHAR_P (t, s, send);
1429 }
1430@@ -2976,6 +2994,7 @@
1431 register char *s, *t;
1432 size_t slen;
1433 char *result, *send;
1434+ int quote_spaces;
1435 DECLARE_MBSTATE;
1436
1437 if (string == 0)
1438@@ -2990,9 +3009,10 @@
1439 if (strchr (string, CTLESC) == 0)
1440 return (strcpy (result, s));
1441
1442+ quote_spaces = (ifs_value && *ifs_value == 0);
1443 while (*s)
1444 {
1445- if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL))
1446+ if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
1447 {
1448 s++;
1449 if (*s == '\0')
[5cd07a2]1450@@ -3954,7 +3974,11 @@
1451 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
1452 patstr++;
1453
1454- pattern = getpattern (patstr, quoted, 1);
1455+ /* Need to pass getpattern newly-allocated memory in case of expansion --
1456+ the expansion code will free the passed string on an error. */
1457+ temp1 = savestring (patstr);
1458+ pattern = getpattern (temp1, quoted, 1);
1459+ free (temp1);
1460
1461 temp1 = (char *)NULL; /* shut up gcc */
1462 switch (vtype)
1463@@ -4123,6 +4147,12 @@
[24cc73c]1464 nfifo = 0;
1465 }
1466
1467+int
1468+fifos_pending ()
1469+{
1470+ return nfifo;
1471+}
1472+
1473 static char *
1474 make_named_pipe ()
1475 {
[5cd07a2]1476@@ -4172,6 +4202,12 @@
[24cc73c]1477 nfds++;
1478 }
1479
1480+int
1481+fifos_pending ()
1482+{
1483+ return 0; /* used for cleanup; not needed with /dev/fd */
1484+}
1485+
1486 void
1487 unlink_fifo_list ()
1488 {
[5cd07a2]1489@@ -4456,7 +4492,15 @@
[24cc73c]1490 /* Add the character to ISTRING, possibly after resizing it. */
1491 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
1492
1493- if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || c == CTLESC || c == CTLNUL)
1494+ /* This is essentially quote_string inline */
1495+ if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
1496+ istring[istring_index++] = CTLESC;
1497+ /* Escape CTLESC and CTLNUL in the output to protect those characters
1498+ from the rest of the word expansions (word splitting and globbing.)
1499+ This is essentially quote_escapes inline. */
1500+ else if (c == CTLESC)
1501+ istring[istring_index++] = CTLESC;
1502+ else if (c == CTLNUL || (c == ' ' && (ifs_value && *ifs_value == 0)))
1503 istring[istring_index++] = CTLESC;
1504
1505 istring[istring_index++] = c;
[5cd07a2]1506@@ -4665,6 +4709,9 @@
[24cc73c]1507
1508 last_command_exit_value = rc;
1509 rc = run_exit_trap ();
1510+#if defined (PROCESS_SUBSTITUTION)
1511+ unlink_fifo_list ();
1512+#endif
1513 exit (rc);
1514 }
1515 else
[5cd07a2]1516@@ -5546,12 +5593,16 @@
[24cc73c]1517 so verify_substring_values just returns the numbers specified and we
1518 rely on array_subrange to understand how to deal with them). */
1519 tt = array_subrange (array_cell (v), e1, e2, starsub, quoted);
1520+#if 0
1521+ /* array_subrange now calls array_quote_escapes as appropriate, so the
1522+ caller no longer needs to. */
1523 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
1524 {
1525 temp = tt ? quote_escapes (tt) : (char *)NULL;
1526 FREE (tt);
1527 }
1528 else
1529+#endif
1530 temp = tt;
1531 break;
1532 #endif
[5cd07a2]1533@@ -5707,6 +5758,11 @@
[24cc73c]1534 vtype &= ~VT_STARSUB;
1535
1536 mflags = 0;
1537+ if (patsub && *patsub == '/')
1538+ {
1539+ mflags |= MATCH_GLOBREP;
1540+ patsub++;
1541+ }
1542
1543 /* Malloc this because expand_string_if_necessary or one of the expansion
1544 functions in its call chain may free it on a substitution error. */
[5cd07a2]1545@@ -5741,13 +5797,12 @@
[24cc73c]1546 }
1547
1548 /* ksh93 doesn't allow the match specifier to be a part of the expanded
1549- pattern. This is an extension. */
1550+ pattern. This is an extension. Make sure we don't anchor the pattern
1551+ at the beginning or end of the string if we're doing global replacement,
1552+ though. */
1553 p = pat;
1554- if (pat && pat[0] == '/')
1555- {
1556- mflags |= MATCH_GLOBREP|MATCH_ANY;
1557- p++;
1558- }
1559+ if (mflags & MATCH_GLOBREP)
1560+ mflags |= MATCH_ANY;
1561 else if (pat && pat[0] == '#')
1562 {
1563 mflags |= MATCH_BEG;
[5cd07a2]1564@@ -5798,12 +5853,16 @@
[24cc73c]1565 #if defined (ARRAY_VARS)
1566 case VT_ARRAYVAR:
1567 temp = array_patsub (array_cell (v), p, rep, mflags);
1568+#if 0
1569+ /* Don't need to do this anymore; array_patsub calls array_quote_escapes
1570+ as appropriate before adding the space separators. */
1571 if (temp && (mflags & MATCH_QUOTED) == 0)
1572 {
1573 tt = quote_escapes (temp);
1574 free (temp);
1575 temp = tt;
1576 }
1577+#endif
1578 break;
1579 #endif
1580 }
[5cd07a2]1581@@ -7607,6 +7666,8 @@
1582 expand_no_split_dollar_star = 0; /* XXX */
1583 expanding_redir = 0;
1584
1585+ top_level_cleanup (); /* from sig.c */
1586+
1587 jump_to_top_level (v);
1588 }
1589
1590@@ -7824,7 +7885,7 @@
1591 else if (fail_glob_expansion != 0)
1592 {
1593 report_error (_("no match: %s"), tlist->word->word);
1594- jump_to_top_level (DISCARD);
1595+ exp_jump_to_top_level (DISCARD);
1596 }
1597 else if (allow_null_glob_expansion == 0)
1598 {
[24cc73c]1599diff -Naur bash-3.2.orig/subst.h bash-3.2/subst.h
[5cd07a2]1600--- bash-3.2.orig/subst.h 2006-09-19 05:34:41.000000000 -0700
1601+++ bash-3.2/subst.h 2007-09-03 21:59:26.000000000 -0700
[24cc73c]1602@@ -222,6 +222,7 @@
1603 extern char *command_substitute __P((char *, int));
1604 extern char *pat_subst __P((char *, char *, char *, int));
1605
1606+extern int fifos_pending __P((void));
1607 extern void unlink_fifo_list __P((void));
1608
1609 extern WORD_LIST *list_string_with_quotes __P((char *));
1610diff -Naur bash-3.2.orig/tests/new-exp.right bash-3.2/tests/new-exp.right
[5cd07a2]1611--- bash-3.2.orig/tests/new-exp.right 2006-08-10 09:00:00.000000000 -0700
1612+++ bash-3.2/tests/new-exp.right 2007-09-03 21:59:12.000000000 -0700
[24cc73c]1613@@ -430,7 +430,7 @@
1614 Case06---1---A B C::---
1615 Case07---3---A:B:C---
1616 Case08---3---A:B:C---
1617-./new-exp.tests: line 506: /${$(($#-1))}: bad substitution
1618+./new-exp.tests: line 506: ${$(($#-1))}: bad substitution
1619 argv[1] = <a>
1620 argv[2] = <b>
1621 argv[3] = <c>
[5cd07a2]1622diff -Naur bash-3.2.orig/variables.c bash-3.2/variables.c
1623--- bash-3.2.orig/variables.c 2006-09-08 10:33:32.000000000 -0700
1624+++ bash-3.2/variables.c 2007-09-03 21:59:34.000000000 -0700
1625@@ -1821,11 +1821,17 @@
1626 oval = value_cell (var);
1627 lval = evalexp (oval, &expok); /* ksh93 seems to do this */
1628 if (expok == 0)
1629- jump_to_top_level (DISCARD);
1630+ {
1631+ top_level_cleanup ();
1632+ jump_to_top_level (DISCARD);
1633+ }
1634 }
1635 rval = evalexp (value, &expok);
1636 if (expok == 0)
1637- jump_to_top_level (DISCARD);
1638+ {
1639+ top_level_cleanup ();
1640+ jump_to_top_level (DISCARD);
1641+ }
1642 if (flags & ASS_APPEND)
1643 rval += lval;
1644 retval = itos (rval);
Note: See TracBrowser for help on using the repository browser.