bash-001-patchlevel25.patch 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. Update bash to patchlevel 25.
  2. It's basically a single patch made out from
  3. http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/ (bash43-001 to 025).
  4. Fixes CVE-2014-6271:
  5. Under certain circumstances, bash will execute user code while processing the
  6. environment for exported function definitions.
  7. Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
  8. diff -Nura bash-4.3.orig/arrayfunc.c bash-4.3/arrayfunc.c
  9. --- bash-4.3.orig/arrayfunc.c 2014-09-24 14:45:32.573985743 -0300
  10. +++ bash-4.3/arrayfunc.c 2014-09-24 14:45:48.858540124 -0300
  11. @@ -179,6 +179,7 @@
  12. array_insert (array_cell (entry), ind, newval);
  13. FREE (newval);
  14. + VUNSETATTR (entry, att_invisible); /* no longer invisible */
  15. return (entry);
  16. }
  17. @@ -597,6 +598,11 @@
  18. if (assoc_p (var))
  19. {
  20. val = expand_assignment_string_to_string (val, 0);
  21. + if (val == 0)
  22. + {
  23. + val = (char *)xmalloc (1);
  24. + val[0] = '\0'; /* like do_assignment_internal */
  25. + }
  26. free_val = 1;
  27. }
  28. diff -Nura bash-4.3.orig/bashline.c bash-4.3/bashline.c
  29. --- bash-4.3.orig/bashline.c 2014-09-24 14:45:32.574985778 -0300
  30. +++ bash-4.3/bashline.c 2014-09-24 14:45:48.851539885 -0300
  31. @@ -4167,9 +4167,16 @@
  32. int qc;
  33. qc = rl_dispatching ? rl_completion_quote_character : 0;
  34. - dfn = bash_dequote_filename ((char *)text, qc);
  35. + /* If rl_completion_found_quote != 0, rl_completion_matches will call the
  36. + filename dequoting function, causing the directory name to be dequoted
  37. + twice. */
  38. + if (rl_dispatching && rl_completion_found_quote == 0)
  39. + dfn = bash_dequote_filename ((char *)text, qc);
  40. + else
  41. + dfn = (char *)text;
  42. m1 = rl_completion_matches (dfn, rl_filename_completion_function);
  43. - free (dfn);
  44. + if (dfn != text)
  45. + free (dfn);
  46. if (m1 == 0 || m1[0] == 0)
  47. return m1;
  48. diff -Nura bash-4.3.orig/builtins/common.h bash-4.3/builtins/common.h
  49. --- bash-4.3.orig/builtins/common.h 2014-09-24 14:45:32.630987683 -0300
  50. +++ bash-4.3/builtins/common.h 2014-09-24 14:45:48.878540805 -0300
  51. @@ -33,6 +33,8 @@
  52. #define SEVAL_RESETLINE 0x010
  53. #define SEVAL_PARSEONLY 0x020
  54. #define SEVAL_NOLONGJMP 0x040
  55. +#define SEVAL_FUNCDEF 0x080 /* only allow function definitions */
  56. +#define SEVAL_ONECMD 0x100 /* only allow a single command */
  57. /* Flags for describe_command, shared between type.def and command.def */
  58. #define CDESC_ALL 0x001 /* type -a */
  59. diff -Nura bash-4.3.orig/builtins/evalstring.c bash-4.3/builtins/evalstring.c
  60. --- bash-4.3.orig/builtins/evalstring.c 2014-09-24 14:45:32.631987717 -0300
  61. +++ bash-4.3/builtins/evalstring.c 2014-09-24 14:45:48.879540839 -0300
  62. @@ -308,6 +308,14 @@
  63. {
  64. struct fd_bitmap *bitmap;
  65. + if ((flags & SEVAL_FUNCDEF) && command->type != cm_function_def)
  66. + {
  67. + internal_warning ("%s: ignoring function definition attempt", from_file);
  68. + should_jump_to_top_level = 0;
  69. + last_result = last_command_exit_value = EX_BADUSAGE;
  70. + break;
  71. + }
  72. +
  73. bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
  74. begin_unwind_frame ("pe_dispose");
  75. add_unwind_protect (dispose_fd_bitmap, bitmap);
  76. @@ -368,6 +376,9 @@
  77. dispose_command (command);
  78. dispose_fd_bitmap (bitmap);
  79. discard_unwind_frame ("pe_dispose");
  80. +
  81. + if (flags & SEVAL_ONECMD)
  82. + break;
  83. }
  84. }
  85. else
  86. diff -Nura bash-4.3.orig/builtins/read.def bash-4.3/builtins/read.def
  87. --- bash-4.3.orig/builtins/read.def 2014-09-24 14:45:32.631987717 -0300
  88. +++ bash-4.3/builtins/read.def 2014-09-24 14:45:48.860540192 -0300
  89. @@ -442,7 +442,10 @@
  90. add_unwind_protect (reset_alarm, (char *)NULL);
  91. #if defined (READLINE)
  92. if (edit)
  93. - add_unwind_protect (reset_attempted_completion_function, (char *)NULL);
  94. + {
  95. + add_unwind_protect (reset_attempted_completion_function, (char *)NULL);
  96. + add_unwind_protect (bashline_reset_event_hook, (char *)NULL);
  97. + }
  98. #endif
  99. falarm (tmsec, tmusec);
  100. }
  101. @@ -1021,6 +1024,7 @@
  102. old_attempted_completion_function = rl_attempted_completion_function;
  103. rl_attempted_completion_function = (rl_completion_func_t *)NULL;
  104. + bashline_set_event_hook ();
  105. if (itext)
  106. {
  107. old_startup_hook = rl_startup_hook;
  108. @@ -1032,6 +1036,7 @@
  109. rl_attempted_completion_function = old_attempted_completion_function;
  110. old_attempted_completion_function = (rl_completion_func_t *)NULL;
  111. + bashline_reset_event_hook ();
  112. if (ret == 0)
  113. return ret;
  114. diff -Nura bash-4.3.orig/execute_cmd.c bash-4.3/execute_cmd.c
  115. --- bash-4.3.orig/execute_cmd.c 2014-09-24 14:45:32.573985743 -0300
  116. +++ bash-4.3/execute_cmd.c 2014-09-24 14:45:48.870540532 -0300
  117. @@ -2409,7 +2409,16 @@
  118. #endif
  119. lstdin = wait_for (lastpid);
  120. #if defined (JOB_CONTROL)
  121. - exec_result = job_exit_status (lastpipe_jid);
  122. + /* If wait_for removes the job from the jobs table, use result of last
  123. + command as pipeline's exit status as usual. The jobs list can get
  124. + frozen and unfrozen at inconvenient times if there are multiple pipelines
  125. + running simultaneously. */
  126. + if (INVALID_JOB (lastpipe_jid) == 0)
  127. + exec_result = job_exit_status (lastpipe_jid);
  128. + else if (pipefail_opt)
  129. + exec_result = exec_result | lstdin; /* XXX */
  130. + /* otherwise we use exec_result */
  131. +
  132. #endif
  133. unfreeze_jobs_list ();
  134. }
  135. diff -Nura bash-4.3.orig/externs.h bash-4.3/externs.h
  136. --- bash-4.3.orig/externs.h 2014-09-24 14:45:32.573985743 -0300
  137. +++ bash-4.3/externs.h 2014-09-24 14:45:48.837539409 -0300
  138. @@ -324,6 +324,7 @@
  139. extern char *sh_backslash_quote __P((char *, const char *, int));
  140. extern char *sh_backslash_quote_for_double_quotes __P((char *));
  141. extern int sh_contains_shell_metas __P((char *));
  142. +extern int sh_contains_quotes __P((char *));
  143. /* declarations for functions defined in lib/sh/spell.c */
  144. extern int spname __P((char *, char *));
  145. diff -Nura bash-4.3.orig/jobs.c bash-4.3/jobs.c
  146. --- bash-4.3.orig/jobs.c 2014-09-24 14:45:32.639987989 -0300
  147. +++ bash-4.3/jobs.c 2014-09-24 14:45:48.843539613 -0300
  148. @@ -3597,6 +3597,7 @@
  149. unwind_protect_int (jobs_list_frozen);
  150. unwind_protect_pointer (the_pipeline);
  151. unwind_protect_pointer (subst_assign_varlist);
  152. + unwind_protect_pointer (this_shell_builtin);
  153. /* We have to add the commands this way because they will be run
  154. in reverse order of adding. We don't want maybe_set_sigchld_trap ()
  155. @@ -4374,7 +4375,7 @@
  156. void
  157. end_job_control ()
  158. {
  159. - if (interactive_shell) /* XXX - should it be interactive? */
  160. + if (interactive_shell || job_control) /* XXX - should it be just job_control? */
  161. {
  162. terminate_stopped_jobs ();
  163. diff -Nura bash-4.3.orig/lib/glob/glob.c bash-4.3/lib/glob/glob.c
  164. --- bash-4.3.orig/lib/glob/glob.c 2014-09-24 14:45:32.652988432 -0300
  165. +++ bash-4.3/lib/glob/glob.c 2014-09-24 14:45:48.853539954 -0300
  166. @@ -123,6 +123,8 @@
  167. extern char *glob_patscan __P((char *, char *, int));
  168. extern wchar_t *glob_patscan_wc __P((wchar_t *, wchar_t *, int));
  169. +extern char *glob_dirscan __P((char *, int));
  170. +
  171. /* Compile `glob_loop.c' for single-byte characters. */
  172. #define CHAR unsigned char
  173. #define INT int
  174. @@ -179,42 +181,53 @@
  175. char *pat, *dname;
  176. int flags;
  177. {
  178. - char *pp, *pe, *t;
  179. - int n, r;
  180. + char *pp, *pe, *t, *se;
  181. + int n, r, negate;
  182. + negate = *pat == '!';
  183. pp = pat + 2;
  184. - pe = pp + strlen (pp) - 1; /*(*/
  185. - if (*pe != ')')
  186. + se = pp + strlen (pp) - 1; /* end of string */
  187. + pe = glob_patscan (pp, se, 0); /* end of extglob pattern (( */
  188. + /* we should check for invalid extglob pattern here */
  189. + if (pe == 0)
  190. return 0;
  191. - if ((t = strchr (pp, '|')) == 0) /* easy case first */
  192. +
  193. + /* if pe != se we have more of the pattern at the end of the extglob
  194. + pattern. Check the easy case first ( */
  195. + if (pe == se && *pe == ')' && (t = strchr (pp, '|')) == 0)
  196. {
  197. *pe = '\0';
  198. +#if defined (HANDLE_MULTIBYTE)
  199. + r = mbskipname (pp, dname, flags);
  200. +#else
  201. r = skipname (pp, dname, flags); /*(*/
  202. +#endif
  203. *pe = ')';
  204. return r;
  205. }
  206. +
  207. + /* check every subpattern */
  208. while (t = glob_patscan (pp, pe, '|'))
  209. {
  210. n = t[-1];
  211. t[-1] = '\0';
  212. +#if defined (HANDLE_MULTIBYTE)
  213. + r = mbskipname (pp, dname, flags);
  214. +#else
  215. r = skipname (pp, dname, flags);
  216. +#endif
  217. t[-1] = n;
  218. if (r == 0) /* if any pattern says not skip, we don't skip */
  219. return r;
  220. pp = t;
  221. } /*(*/
  222. - if (pp == pe) /* glob_patscan might find end of pattern */
  223. + /* glob_patscan might find end of pattern */
  224. + if (pp == se)
  225. return r;
  226. - *pe = '\0';
  227. -# if defined (HANDLE_MULTIBYTE)
  228. - r = mbskipname (pp, dname, flags); /*(*/
  229. -# else
  230. - r = skipname (pp, dname, flags); /*(*/
  231. -# endif
  232. - *pe = ')';
  233. - return r;
  234. + /* but if it doesn't then we didn't match a leading dot */
  235. + return 0;
  236. }
  237. #endif
  238. @@ -277,20 +290,23 @@
  239. int flags;
  240. {
  241. #if EXTENDED_GLOB
  242. - wchar_t *pp, *pe, *t, n;
  243. - int r;
  244. + wchar_t *pp, *pe, *t, n, *se;
  245. + int r, negate;
  246. + negate = *pat == L'!';
  247. pp = pat + 2;
  248. - pe = pp + wcslen (pp) - 1; /*(*/
  249. - if (*pe != L')')
  250. - return 0;
  251. - if ((t = wcschr (pp, L'|')) == 0)
  252. + se = pp + wcslen (pp) - 1; /*(*/
  253. + pe = glob_patscan_wc (pp, se, 0);
  254. +
  255. + if (pe == se && *pe == ')' && (t = wcschr (pp, L'|')) == 0)
  256. {
  257. *pe = L'\0';
  258. r = wchkname (pp, dname); /*(*/
  259. *pe = L')';
  260. return r;
  261. }
  262. +
  263. + /* check every subpattern */
  264. while (t = glob_patscan_wc (pp, pe, '|'))
  265. {
  266. n = t[-1];
  267. @@ -305,10 +321,8 @@
  268. if (pp == pe) /* glob_patscan_wc might find end of pattern */
  269. return r;
  270. - *pe = L'\0';
  271. - r = wchkname (pp, dname); /*(*/
  272. - *pe = L')';
  273. - return r;
  274. + /* but if it doesn't then we didn't match a leading dot */
  275. + return 0;
  276. #else
  277. return (wchkname (pat, dname));
  278. #endif
  279. @@ -1006,7 +1020,7 @@
  280. {
  281. char **result;
  282. unsigned int result_size;
  283. - char *directory_name, *filename, *dname;
  284. + char *directory_name, *filename, *dname, *fn;
  285. unsigned int directory_len;
  286. int free_dirname; /* flag */
  287. int dflags;
  288. @@ -1022,6 +1036,18 @@
  289. /* Find the filename. */
  290. filename = strrchr (pathname, '/');
  291. +#if defined (EXTENDED_GLOB)
  292. + if (filename && extended_glob)
  293. + {
  294. + fn = glob_dirscan (pathname, '/');
  295. +#if DEBUG_MATCHING
  296. + if (fn != filename)
  297. + fprintf (stderr, "glob_filename: glob_dirscan: fn (%s) != filename (%s)\n", fn ? fn : "(null)", filename);
  298. +#endif
  299. + filename = fn;
  300. + }
  301. +#endif
  302. +
  303. if (filename == NULL)
  304. {
  305. filename = pathname;
  306. diff -Nura bash-4.3.orig/lib/glob/gmisc.c bash-4.3/lib/glob/gmisc.c
  307. --- bash-4.3.orig/lib/glob/gmisc.c 2014-09-24 14:45:32.652988432 -0300
  308. +++ bash-4.3/lib/glob/gmisc.c 2014-09-24 14:45:48.854539988 -0300
  309. @@ -42,6 +42,8 @@
  310. #define WLPAREN L'('
  311. #define WRPAREN L')'
  312. +extern char *glob_patscan __P((char *, char *, int));
  313. +
  314. /* Return 1 of the first character of WSTRING could match the first
  315. character of pattern WPAT. Wide character version. */
  316. int
  317. @@ -210,6 +212,7 @@
  318. case '+':
  319. case '!':
  320. case '@':
  321. + case '?':
  322. return (pat[1] == LPAREN);
  323. default:
  324. return 0;
  325. @@ -374,3 +377,34 @@
  326. return matlen;
  327. }
  328. +
  329. +/* Skip characters in PAT and return the final occurrence of DIRSEP. This
  330. + is only called when extended_glob is set, so we have to skip over extglob
  331. + patterns x(...) */
  332. +char *
  333. +glob_dirscan (pat, dirsep)
  334. + char *pat;
  335. + int dirsep;
  336. +{
  337. + char *p, *d, *pe, *se;
  338. +
  339. + d = pe = se = 0;
  340. + for (p = pat; p && *p; p++)
  341. + {
  342. + if (extglob_pattern_p (p))
  343. + {
  344. + if (se == 0)
  345. + se = p + strlen (p) - 1;
  346. + pe = glob_patscan (p + 2, se, 0);
  347. + if (pe == 0)
  348. + continue;
  349. + else if (*pe == 0)
  350. + break;
  351. + p = pe - 1; /* will do increment above */
  352. + continue;
  353. + }
  354. + if (*p == dirsep)
  355. + d = p;
  356. + }
  357. + return d;
  358. +}
  359. diff -Nura bash-4.3.orig/lib/readline/display.c bash-4.3/lib/readline/display.c
  360. --- bash-4.3.orig/lib/readline/display.c 2014-09-24 14:45:32.652988432 -0300
  361. +++ bash-4.3/lib/readline/display.c 2014-09-24 14:45:48.845539681 -0300
  362. @@ -1637,7 +1637,7 @@
  363. /* If we are changing the number of invisible characters in a line, and
  364. the spot of first difference is before the end of the invisible chars,
  365. lendiff needs to be adjusted. */
  366. - if (current_line == 0 && !_rl_horizontal_scroll_mode &&
  367. + if (current_line == 0 && /* !_rl_horizontal_scroll_mode && */
  368. current_invis_chars != visible_wrap_offset)
  369. {
  370. if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
  371. @@ -1825,8 +1825,13 @@
  372. else
  373. _rl_last_c_pos += bytes_to_insert;
  374. + /* XXX - we only want to do this if we are at the end of the line
  375. + so we move there with _rl_move_cursor_relative */
  376. if (_rl_horizontal_scroll_mode && ((oe-old) > (ne-new)))
  377. - goto clear_rest_of_line;
  378. + {
  379. + _rl_move_cursor_relative (ne-new, new);
  380. + goto clear_rest_of_line;
  381. + }
  382. }
  383. }
  384. /* Otherwise, print over the existing material. */
  385. @@ -2677,7 +2682,8 @@
  386. {
  387. if (_rl_echoing_p)
  388. {
  389. - _rl_move_vert (_rl_vis_botlin);
  390. + if (_rl_vis_botlin > 0) /* minor optimization plus bug fix */
  391. + _rl_move_vert (_rl_vis_botlin);
  392. _rl_vis_botlin = 0;
  393. fflush (rl_outstream);
  394. rl_restart_output (1, 0);
  395. diff -Nura bash-4.3.orig/lib/readline/input.c bash-4.3/lib/readline/input.c
  396. --- bash-4.3.orig/lib/readline/input.c 2014-09-24 14:45:32.651988398 -0300
  397. +++ bash-4.3/lib/readline/input.c 2014-09-24 14:45:48.860540192 -0300
  398. @@ -534,8 +534,16 @@
  399. return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
  400. else if (_rl_caught_signal == SIGHUP || _rl_caught_signal == SIGTERM)
  401. return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
  402. + /* keyboard-generated signals of interest */
  403. else if (_rl_caught_signal == SIGINT || _rl_caught_signal == SIGQUIT)
  404. RL_CHECK_SIGNALS ();
  405. + /* non-keyboard-generated signals of interest */
  406. + else if (_rl_caught_signal == SIGALRM
  407. +#if defined (SIGVTALRM)
  408. + || _rl_caught_signal == SIGVTALRM
  409. +#endif
  410. + )
  411. + RL_CHECK_SIGNALS ();
  412. if (rl_signal_event_hook)
  413. (*rl_signal_event_hook) ();
  414. diff -Nura bash-4.3.orig/lib/readline/misc.c bash-4.3/lib/readline/misc.c
  415. --- bash-4.3.orig/lib/readline/misc.c 2014-09-24 14:45:32.652988432 -0300
  416. +++ bash-4.3/lib/readline/misc.c 2014-09-24 14:45:48.867540430 -0300
  417. @@ -461,6 +461,7 @@
  418. saved_undo_list = 0;
  419. /* Set up rl_line_buffer and other variables from history entry */
  420. rl_replace_from_history (entry, 0); /* entry->line is now current */
  421. + entry->data = 0; /* entry->data is now current undo list */
  422. /* Undo all changes to this history entry */
  423. while (rl_undo_list)
  424. rl_do_undo ();
  425. @@ -468,7 +469,6 @@
  426. the timestamp. */
  427. FREE (entry->line);
  428. entry->line = savestring (rl_line_buffer);
  429. - entry->data = 0;
  430. }
  431. entry = previous_history ();
  432. }
  433. diff -Nura bash-4.3.orig/lib/readline/readline.c bash-4.3/lib/readline/readline.c
  434. --- bash-4.3.orig/lib/readline/readline.c 2014-09-24 14:45:32.652988432 -0300
  435. +++ bash-4.3/lib/readline/readline.c 2014-09-24 14:45:48.819538797 -0300
  436. @@ -744,7 +744,8 @@
  437. r = _rl_subseq_result (r, cxt->oldmap, cxt->okey, (cxt->flags & KSEQ_SUBSEQ));
  438. RL_CHECK_SIGNALS ();
  439. - if (r == 0) /* success! */
  440. + /* We only treat values < 0 specially to simulate recursion. */
  441. + if (r >= 0 || (r == -1 && (cxt->flags & KSEQ_SUBSEQ) == 0)) /* success! or failure! */
  442. {
  443. _rl_keyseq_chain_dispose ();
  444. RL_UNSETSTATE (RL_STATE_MULTIKEY);
  445. @@ -964,7 +965,7 @@
  446. #if defined (VI_MODE)
  447. if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap &&
  448. key != ANYOTHERKEY &&
  449. - rl_key_sequence_length == 1 && /* XXX */
  450. + _rl_dispatching_keymap == vi_movement_keymap &&
  451. _rl_vi_textmod_command (key))
  452. _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
  453. #endif
  454. diff -Nura bash-4.3.orig/lib/sh/shquote.c bash-4.3/lib/sh/shquote.c
  455. --- bash-4.3.orig/lib/sh/shquote.c 2014-09-24 14:45:32.654988500 -0300
  456. +++ bash-4.3/lib/sh/shquote.c 2014-09-24 14:45:48.837539409 -0300
  457. @@ -311,3 +311,17 @@
  458. return (0);
  459. }
  460. +
  461. +int
  462. +sh_contains_quotes (string)
  463. + char *string;
  464. +{
  465. + char *s;
  466. +
  467. + for (s = string; s && *s; s++)
  468. + {
  469. + if (*s == '\'' || *s == '"' || *s == '\\')
  470. + return 1;
  471. + }
  472. + return 0;
  473. +}
  474. diff -Nura bash-4.3.orig/parse.y bash-4.3/parse.y
  475. --- bash-4.3.orig/parse.y 2014-09-24 14:45:32.650988364 -0300
  476. +++ bash-4.3/parse.y 2014-09-24 14:45:48.863540294 -0300
  477. @@ -2424,7 +2424,7 @@
  478. not already end in an EOF character. */
  479. if (shell_input_line_terminator != EOF)
  480. {
  481. - if (shell_input_line_size < SIZE_MAX && shell_input_line_len > shell_input_line_size - 3)
  482. + if (shell_input_line_size < SIZE_MAX-3 && (shell_input_line_len+3 > shell_input_line_size))
  483. shell_input_line = (char *)xrealloc (shell_input_line,
  484. 1 + (shell_input_line_size += 2));
  485. @@ -2642,7 +2642,7 @@
  486. int r;
  487. r = 0;
  488. - while (need_here_doc)
  489. + while (need_here_doc > 0)
  490. {
  491. parser_state |= PST_HEREDOC;
  492. make_here_document (redir_stack[r++], line_number);
  493. @@ -3398,7 +3398,7 @@
  494. within a double-quoted ${...} construct "an even number of
  495. unescaped double-quotes or single-quotes, if any, shall occur." */
  496. /* This was changed in Austin Group Interp 221 */
  497. - if MBTEST(posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && (flags & P_DQUOTE) && (flags & P_DOLBRACE) && ch == '\'')
  498. + if MBTEST(posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && dolbrace_state != DOLBRACE_QUOTE2 && (flags & P_DQUOTE) && (flags & P_DOLBRACE) && ch == '\'')
  499. continue;
  500. /* Could also check open == '`' if we want to parse grouping constructs
  501. @@ -6075,6 +6075,7 @@
  502. ps->expand_aliases = expand_aliases;
  503. ps->echo_input_at_read = echo_input_at_read;
  504. + ps->need_here_doc = need_here_doc;
  505. ps->token = token;
  506. ps->token_buffer_size = token_buffer_size;
  507. @@ -6123,6 +6124,7 @@
  508. expand_aliases = ps->expand_aliases;
  509. echo_input_at_read = ps->echo_input_at_read;
  510. + need_here_doc = ps->need_here_doc;
  511. FREE (token);
  512. token = ps->token;
  513. diff -Nura bash-4.3.orig/patchlevel.h bash-4.3/patchlevel.h
  514. --- bash-4.3.orig/patchlevel.h 2014-09-24 14:45:32.639987989 -0300
  515. +++ bash-4.3/patchlevel.h 2014-09-24 14:45:48.883540975 -0300
  516. @@ -25,6 +25,6 @@
  517. regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
  518. looks for to find the patch level (for the sccs version string). */
  519. -#define PATCHLEVEL 0
  520. +#define PATCHLEVEL 25
  521. #endif /* _PATCHLEVEL_H_ */
  522. diff -Nura bash-4.3.orig/pcomplete.c bash-4.3/pcomplete.c
  523. --- bash-4.3.orig/pcomplete.c 2014-09-24 14:45:32.637987921 -0300
  524. +++ bash-4.3/pcomplete.c 2014-09-24 14:45:48.838539443 -0300
  525. @@ -183,6 +183,7 @@
  526. COMPSPEC *pcomp_curcs;
  527. const char *pcomp_curcmd;
  528. +const char *pcomp_curtxt;
  529. #ifdef DEBUG
  530. /* Debugging code */
  531. @@ -753,6 +754,32 @@
  532. quoted strings. */
  533. dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
  534. }
  535. + /* Intended to solve a mismatched assumption by bash-completion. If
  536. + the text to be completed is empty, but bash-completion turns it into
  537. + a quoted string ('') assuming that this code will dequote it before
  538. + calling readline, do the dequoting. */
  539. + else if (iscompgen && iscompleting &&
  540. + pcomp_curtxt && *pcomp_curtxt == 0 &&
  541. + text && (*text == '\'' || *text == '"') && text[1] == text[0] && text[2] == 0 &&
  542. + rl_filename_dequoting_function)
  543. + dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
  544. + /* Another mismatched assumption by bash-completion. If compgen is being
  545. + run as part of bash-completion, and the argument to compgen is not
  546. + the same as the word originally passed to the programmable completion
  547. + code, dequote the argument if it has quote characters. It's an
  548. + attempt to detect when bash-completion is quoting its filename
  549. + argument before calling compgen. */
  550. + /* We could check whether gen_shell_function_matches is in the call
  551. + stack by checking whether the gen-shell-function-matches tag is in
  552. + the unwind-protect stack, but there's no function to do that yet.
  553. + We could simply check whether we're executing in a function by
  554. + checking variable_context, and may end up doing that. */
  555. + else if (iscompgen && iscompleting && rl_filename_dequoting_function &&
  556. + pcomp_curtxt && text &&
  557. + STREQ (pcomp_curtxt, text) == 0 &&
  558. + variable_context &&
  559. + sh_contains_quotes (text)) /* guess */
  560. + dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
  561. else
  562. dfn = savestring (text);
  563. }
  564. @@ -1522,7 +1549,7 @@
  565. COMPSPEC **lastcs;
  566. {
  567. COMPSPEC *cs, *oldcs;
  568. - const char *oldcmd;
  569. + const char *oldcmd, *oldtxt;
  570. STRINGLIST *ret;
  571. cs = progcomp_search (ocmd);
  572. @@ -1545,14 +1572,17 @@
  573. oldcs = pcomp_curcs;
  574. oldcmd = pcomp_curcmd;
  575. + oldtxt = pcomp_curtxt;
  576. pcomp_curcs = cs;
  577. pcomp_curcmd = cmd;
  578. + pcomp_curtxt = word;
  579. ret = gen_compspec_completions (cs, cmd, word, start, end, foundp);
  580. pcomp_curcs = oldcs;
  581. pcomp_curcmd = oldcmd;
  582. + pcomp_curtxt = oldtxt;
  583. /* We need to conditionally handle setting *retryp here */
  584. if (retryp)
  585. diff -Nura bash-4.3.orig/shell.h bash-4.3/shell.h
  586. --- bash-4.3.orig/shell.h 2014-09-24 14:45:32.573985743 -0300
  587. +++ bash-4.3/shell.h 2014-09-24 14:45:48.862540260 -0300
  588. @@ -168,7 +168,8 @@
  589. /* flags state affecting the parser */
  590. int expand_aliases;
  591. int echo_input_at_read;
  592. -
  593. + int need_here_doc;
  594. +
  595. } sh_parser_state_t;
  596. typedef struct _sh_input_line_state_t {
  597. diff -Nura bash-4.3.orig/subst.c bash-4.3/subst.c
  598. --- bash-4.3.orig/subst.c 2014-09-24 14:45:32.640988023 -0300
  599. +++ bash-4.3/subst.c 2014-09-24 14:45:48.882540941 -0300
  600. @@ -1192,12 +1192,18 @@
  601. Start extracting at (SINDEX) as if we had just seen "<(".
  602. Make (SINDEX) get the position of the matching ")". */ /*))*/
  603. char *
  604. -extract_process_subst (string, starter, sindex)
  605. +extract_process_subst (string, starter, sindex, xflags)
  606. char *string;
  607. char *starter;
  608. int *sindex;
  609. + int xflags;
  610. {
  611. +#if 0
  612. return (extract_delimited_string (string, sindex, starter, "(", ")", SX_COMMAND));
  613. +#else
  614. + xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0);
  615. + return (xparse_dolparen (string, string+*sindex, sindex, xflags));
  616. +#endif
  617. }
  618. #endif /* PROCESS_SUBSTITUTION */
  619. @@ -1785,7 +1791,7 @@
  620. si = i + 2;
  621. if (string[si] == '\0')
  622. CQ_RETURN(si);
  623. - temp = extract_process_subst (string, (c == '<') ? "<(" : ">(", &si);
  624. + temp = extract_process_subst (string, (c == '<') ? "<(" : ">(", &si, 0);
  625. free (temp); /* no SX_ALLOC here */
  626. i = si;
  627. if (string[i] == '\0')
  628. @@ -3248,8 +3254,10 @@
  629. if (w->word == 0 || w->word[0] == '\0')
  630. return ((char *)NULL);
  631. + expand_no_split_dollar_star = 1;
  632. w->flags |= W_NOSPLIT2;
  633. l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
  634. + expand_no_split_dollar_star = 0;
  635. if (l)
  636. {
  637. if (special == 0) /* LHS */
  638. @@ -7366,7 +7374,13 @@
  639. }
  640. if (want_indir)
  641. - tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
  642. + {
  643. + tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
  644. + /* Turn off the W_ARRAYIND flag because there is no way for this function
  645. + to return the index we're supposed to be using. */
  646. + if (tdesc && tdesc->flags)
  647. + tdesc->flags &= ~W_ARRAYIND;
  648. + }
  649. else
  650. tdesc = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND|(pflags&(PF_NOSPLIT2|PF_ASSIGNRHS)), &ind);
  651. @@ -7847,6 +7861,10 @@
  652. We also want to make sure that splitting is done no matter what --
  653. according to POSIX.2, this expands to a list of the positional
  654. parameters no matter what IFS is set to. */
  655. + /* XXX - what to do when in a context where word splitting is not
  656. + performed? Even when IFS is not the default, posix seems to imply
  657. + that we behave like unquoted $* ? Maybe we should use PF_NOSPLIT2
  658. + here. */
  659. temp = string_list_dollar_at (list, (pflags & PF_ASSIGNRHS) ? (quoted|Q_DOUBLE_QUOTES) : quoted);
  660. tflag |= W_DOLLARAT;
  661. @@ -8029,7 +8047,9 @@
  662. goto return0;
  663. }
  664. - else if (var = find_variable_last_nameref (temp1))
  665. + else if (var && (invisible_p (var) || var_isset (var) == 0))
  666. + temp = (char *)NULL;
  667. + else if ((var = find_variable_last_nameref (temp1)) && var_isset (var) && invisible_p (var) == 0)
  668. {
  669. temp = nameref_cell (var);
  670. #if defined (ARRAY_VARS)
  671. @@ -8243,7 +8263,7 @@
  672. else
  673. t_index = sindex + 1; /* skip past both '<' and LPAREN */
  674. - temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
  675. + temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index, 0); /*))*/
  676. sindex = t_index;
  677. /* If the process substitution specification is `<()', we want to
  678. @@ -8816,6 +8836,7 @@
  679. else
  680. {
  681. char *ifs_chars;
  682. + char *tstring;
  683. ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
  684. @@ -8830,11 +8851,36 @@
  685. regardless of what else has happened to IFS since the expansion. */
  686. if (split_on_spaces)
  687. list = list_string (istring, " ", 1); /* XXX quoted == 1? */
  688. + /* If we have $@ (has_dollar_at != 0) and we are in a context where we
  689. + don't want to split the result (W_NOSPLIT2), and we are not quoted,
  690. + we have already separated the arguments with the first character of
  691. + $IFS. In this case, we want to return a list with a single word
  692. + with the separator possibly replaced with a space (it's what other
  693. + shells seem to do).
  694. + quoted_dollar_at is internal to this function and is set if we are
  695. + passed an argument that is unquoted (quoted == 0) but we encounter a
  696. + double-quoted $@ while expanding it. */
  697. + else if (has_dollar_at && quoted_dollar_at == 0 && ifs_chars && quoted == 0 && (word->flags & W_NOSPLIT2))
  698. + {
  699. + /* Only split and rejoin if we have to */
  700. + if (*ifs_chars && *ifs_chars != ' ')
  701. + {
  702. + list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
  703. + tstring = string_list (list);
  704. + }
  705. + else
  706. + tstring = istring;
  707. + tword = make_bare_word (tstring);
  708. + if (tstring != istring)
  709. + free (tstring);
  710. + goto set_word_flags;
  711. + }
  712. else if (has_dollar_at && ifs_chars)
  713. list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
  714. else
  715. {
  716. tword = make_bare_word (istring);
  717. +set_word_flags:
  718. if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
  719. tword->flags |= W_QUOTED;
  720. if (word->flags & W_ASSIGNMENT)
  721. diff -Nura bash-4.3.orig/subst.h bash-4.3/subst.h
  722. --- bash-4.3.orig/subst.h 2014-09-24 14:45:32.655988534 -0300
  723. +++ bash-4.3/subst.h 2014-09-24 14:45:48.871540566 -0300
  724. @@ -82,7 +82,7 @@
  725. /* Extract the <( or >( construct in STRING, and return a new string.
  726. Start extracting at (SINDEX) as if we had just seen "<(".
  727. Make (SINDEX) get the position just after the matching ")". */
  728. -extern char *extract_process_subst __P((char *, char *, int *));
  729. +extern char *extract_process_subst __P((char *, char *, int *, int));
  730. #endif /* PROCESS_SUBSTITUTION */
  731. /* Extract the name of the variable to bind to from the assignment string. */
  732. diff -Nura bash-4.3.orig/test.c bash-4.3/test.c
  733. --- bash-4.3.orig/test.c 2014-09-24 14:45:32.650988364 -0300
  734. +++ bash-4.3/test.c 2014-09-24 14:45:48.814538631 -0300
  735. @@ -646,8 +646,8 @@
  736. return (v && invisible_p (v) == 0 && var_isset (v) ? TRUE : FALSE);
  737. case 'R':
  738. - v = find_variable (arg);
  739. - return (v && invisible_p (v) == 0 && var_isset (v) && nameref_p (v) ? TRUE : FALSE);
  740. + v = find_variable_noref (arg);
  741. + return ((v && invisible_p (v) == 0 && var_isset (v) && nameref_p (v)) ? TRUE : FALSE);
  742. }
  743. /* We can't actually get here, but this shuts up gcc. */
  744. @@ -723,6 +723,7 @@
  745. case 'o': case 'p': case 'r': case 's': case 't':
  746. case 'u': case 'v': case 'w': case 'x': case 'z':
  747. case 'G': case 'L': case 'O': case 'S': case 'N':
  748. + case 'R':
  749. return (1);
  750. }
  751. diff -Nura bash-4.3.orig/trap.c bash-4.3/trap.c
  752. --- bash-4.3.orig/trap.c 2014-09-24 14:45:32.637987921 -0300
  753. +++ bash-4.3/trap.c 2014-09-24 14:45:48.815538661 -0300
  754. @@ -920,7 +920,8 @@
  755. subst_assign_varlist = 0;
  756. #if defined (JOB_CONTROL)
  757. - save_pipeline (1); /* XXX only provides one save level */
  758. + if (sig != DEBUG_TRAP) /* run_debug_trap does this */
  759. + save_pipeline (1); /* XXX only provides one save level */
  760. #endif
  761. /* If we're in a function, make sure return longjmps come here, too. */
  762. @@ -940,7 +941,8 @@
  763. trap_exit_value = last_command_exit_value;
  764. #if defined (JOB_CONTROL)
  765. - restore_pipeline (1);
  766. + if (sig != DEBUG_TRAP) /* run_debug_trap does this */
  767. + restore_pipeline (1);
  768. #endif
  769. subst_assign_varlist = save_subst_varlist;
  770. diff -Nura bash-4.3.orig/variables.c bash-4.3/variables.c
  771. --- bash-4.3.orig/variables.c 2014-09-24 14:45:32.632987751 -0300
  772. +++ bash-4.3/variables.c 2014-09-24 14:45:48.880540873 -0300
  773. @@ -358,13 +358,11 @@
  774. temp_string[char_index] = ' ';
  775. strcpy (temp_string + char_index + 1, string);
  776. - if (posixly_correct == 0 || legal_identifier (name))
  777. - parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
  778. -
  779. - /* Ancient backwards compatibility. Old versions of bash exported
  780. - functions like name()=() {...} */
  781. - if (name[char_index - 1] == ')' && name[char_index - 2] == '(')
  782. - name[char_index - 2] = '\0';
  783. + /* Don't import function names that are invalid identifiers from the
  784. + environment, though we still allow them to be defined as shell
  785. + variables. */
  786. + if (legal_identifier (name))
  787. + parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
  788. if (temp_var = find_function (name))
  789. {
  790. @@ -381,10 +379,6 @@
  791. last_command_exit_value = 1;
  792. report_error (_("error importing function definition for `%s'"), name);
  793. }
  794. -
  795. - /* ( */
  796. - if (name[char_index - 1] == ')' && name[char_index - 2] == '\0')
  797. - name[char_index - 2] = '('; /* ) */
  798. }
  799. #if defined (ARRAY_VARS)
  800. # if ARRAY_EXPORT
  801. @@ -2197,10 +2191,7 @@
  802. /* local foo; local foo; is a no-op. */
  803. old_var = find_variable (name);
  804. if (old_var && local_p (old_var) && old_var->context == variable_context)
  805. - {
  806. - VUNSETATTR (old_var, att_invisible); /* XXX */
  807. - return (old_var);
  808. - }
  809. + return (old_var);
  810. was_tmpvar = old_var && tempvar_p (old_var);
  811. /* If we're making a local variable in a shell function, the temporary env
  812. diff -Nura bash-4.3.orig/y.tab.c bash-4.3/y.tab.c
  813. --- bash-4.3.orig/y.tab.c 2014-09-24 14:45:32.573985743 -0300
  814. +++ bash-4.3/y.tab.c 2014-09-24 14:45:48.865540362 -0300
  815. @@ -4736,7 +4736,7 @@
  816. not already end in an EOF character. */
  817. if (shell_input_line_terminator != EOF)
  818. {
  819. - if (shell_input_line_size < SIZE_MAX && shell_input_line_len > shell_input_line_size - 3)
  820. + if (shell_input_line_size < SIZE_MAX-3 && (shell_input_line_len+3 > shell_input_line_size))
  821. shell_input_line = (char *)xrealloc (shell_input_line,
  822. 1 + (shell_input_line_size += 2));
  823. @@ -4954,7 +4954,7 @@
  824. int r;
  825. r = 0;
  826. - while (need_here_doc)
  827. + while (need_here_doc > 0)
  828. {
  829. parser_state |= PST_HEREDOC;
  830. make_here_document (redir_stack[r++], line_number);
  831. @@ -5710,7 +5710,7 @@
  832. within a double-quoted ${...} construct "an even number of
  833. unescaped double-quotes or single-quotes, if any, shall occur." */
  834. /* This was changed in Austin Group Interp 221 */
  835. - if MBTEST(posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && (flags & P_DQUOTE) && (flags & P_DOLBRACE) && ch == '\'')
  836. + if MBTEST(posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && dolbrace_state != DOLBRACE_QUOTE2 && (flags & P_DQUOTE) && (flags & P_DOLBRACE) && ch == '\'')
  837. continue;
  838. /* Could also check open == '`' if we want to parse grouping constructs
  839. @@ -8387,6 +8387,7 @@
  840. ps->expand_aliases = expand_aliases;
  841. ps->echo_input_at_read = echo_input_at_read;
  842. + ps->need_here_doc = need_here_doc;
  843. ps->token = token;
  844. ps->token_buffer_size = token_buffer_size;
  845. @@ -8435,6 +8436,7 @@
  846. expand_aliases = ps->expand_aliases;
  847. echo_input_at_read = ps->echo_input_at_read;
  848. + need_here_doc = ps->need_here_doc;
  849. FREE (token);
  850. token = ps->token;