bash31-010 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. BASH PATCH REPORT
  2. =================
  3. Bash-Release: 3.1
  4. Patch-ID: bash31-010
  5. Bug-Reported-by: vw@vonwolff.de
  6. Bug-Reference-ID: <20060123135234.1AC2F1D596@wst07.vonwolff.de>
  7. Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2006-01/msg00090.html
  8. Bug-Description:
  9. There is a difference in behavior between bash-3.0 and bash-3.1 involving
  10. parsing of single- and double-quoted strings occurring in old-style
  11. command substitution. The difference has to do with how backslashes are
  12. processed. This patch restores a measure of backwards compatibility while
  13. the question of POSIX conformance and ultimately correct behavior is discussed.
  14. THIS IS AN UPDATED PATCH. USE THIS COMMAND TO REVERSE THE EFFECTS OF
  15. THE ORIGINAL PATCH. THE CURRENT DIRECTORY MUST BE THE BASH-3.1 SOURCE
  16. DIRECTORY.
  17. patch -p0 -R < bash31-010.orig
  18. Then apply this patch as usual.
  19. Patch:
  20. *** bash-3.1/parse.y Fri Nov 11 23:14:18 2005
  21. --- bash-3.1/parse.y Thu Feb 23 08:21:12 2006
  22. ***************
  23. *** 2716,2721 ****
  24. --- 2723,2729 ----
  25. #define P_ALLOWESC 0x02
  26. #define P_DQUOTE 0x04
  27. #define P_COMMAND 0x08 /* parsing a command, so look for comments */
  28. + #define P_BACKQUOTE 0x10 /* parsing a backquoted command substitution */
  29. static char matched_pair_error;
  30. static char *
  31. ***************
  32. *** 2725,2736 ****
  33. int *lenp, flags;
  34. {
  35. int count, ch, was_dollar, in_comment, check_comment;
  36. ! int pass_next_character, nestlen, ttranslen, start_lineno;
  37. char *ret, *nestret, *ttrans;
  38. int retind, retsize, rflags;
  39. count = 1;
  40. ! pass_next_character = was_dollar = in_comment = 0;
  41. check_comment = (flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0;
  42. /* RFLAGS is the set of flags we want to pass to recursive calls. */
  43. --- 2733,2744 ----
  44. int *lenp, flags;
  45. {
  46. int count, ch, was_dollar, in_comment, check_comment;
  47. ! int pass_next_character, backq_backslash, nestlen, ttranslen, start_lineno;
  48. char *ret, *nestret, *ttrans;
  49. int retind, retsize, rflags;
  50. count = 1;
  51. ! pass_next_character = backq_backslash = was_dollar = in_comment = 0;
  52. check_comment = (flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0;
  53. /* RFLAGS is the set of flags we want to pass to recursive calls. */
  54. ***************
  55. *** 2742,2752 ****
  56. start_lineno = line_number;
  57. while (count)
  58. {
  59. ! #if 0
  60. ! ch = shell_getc ((qc != '\'' || (flags & P_ALLOWESC)) && pass_next_character == 0);
  61. ! #else
  62. ! ch = shell_getc (qc != '\'' && pass_next_character == 0);
  63. ! #endif
  64. if (ch == EOF)
  65. {
  66. free (ret);
  67. --- 2750,2757 ----
  68. start_lineno = line_number;
  69. while (count)
  70. {
  71. ! ch = shell_getc (qc != '\'' && pass_next_character == 0 && backq_backslash == 0);
  72. !
  73. if (ch == EOF)
  74. {
  75. free (ret);
  76. ***************
  77. *** 2771,2779 ****
  78. continue;
  79. }
  80. /* Not exactly right yet */
  81. ! else if (check_comment && in_comment == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || whitespace (ret[retind -1])))
  82. in_comment = 1;
  83. if (pass_next_character) /* last char was backslash */
  84. {
  85. pass_next_character = 0;
  86. --- 2776,2791 ----
  87. continue;
  88. }
  89. /* Not exactly right yet */
  90. ! else if MBTEST(check_comment && in_comment == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || whitespace (ret[retind - 1])))
  91. in_comment = 1;
  92. + /* last char was backslash inside backquoted command substitution */
  93. + if (backq_backslash)
  94. + {
  95. + backq_backslash = 0;
  96. + /* Placeholder for adding special characters */
  97. + }
  98. +
  99. if (pass_next_character) /* last char was backslash */
  100. {
  101. pass_next_character = 0;
  102. ***************
  103. *** 2814,2819 ****
  104. --- 2824,2831 ----
  105. {
  106. if MBTEST((flags & P_ALLOWESC) && ch == '\\')
  107. pass_next_character++;
  108. + else if MBTEST((flags & P_BACKQUOTE) && ch == '\\')
  109. + backq_backslash++;
  110. continue;
  111. }
  112. ***************
  113. *** 2898,2904 ****
  114. }
  115. else if MBTEST(qc == '`' && (ch == '"' || ch == '\'') && in_comment == 0)
  116. {
  117. ! nestret = parse_matched_pair (0, ch, ch, &nestlen, rflags);
  118. goto add_nestret;
  119. }
  120. else if MBTEST(was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
  121. --- 2910,2920 ----
  122. }
  123. else if MBTEST(qc == '`' && (ch == '"' || ch == '\'') && in_comment == 0)
  124. {
  125. ! /* Add P_BACKQUOTE so backslash quotes the next character and
  126. ! shell_getc does the right thing with \<newline>. We do this for
  127. ! a measure of backwards compatibility -- it's not strictly the
  128. ! right POSIX thing. */
  129. ! nestret = parse_matched_pair (0, ch, ch, &nestlen, rflags|P_BACKQUOTE);
  130. goto add_nestret;
  131. }
  132. else if MBTEST(was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
  133. *** bash-3.1/patchlevel.h Wed Jul 20 13:58:20 2005
  134. --- bash-3.1/patchlevel.h Wed Dec 7 13:48:42 2005
  135. ***************
  136. *** 26,30 ****
  137. looks for to find the patch level (for the sccs version string). */
  138. ! #define PATCHLEVEL 9
  139. #endif /* _PATCHLEVEL_H_ */
  140. --- 26,30 ----
  141. looks for to find the patch level (for the sccs version string). */
  142. ! #define PATCHLEVEL 10
  143. #endif /* _PATCHLEVEL_H_ */