summaryrefslogtreecommitdiffstats
path: root/package/bash/bash31-010
blob: 19277a88f8a44086773d7d21423fc8db4eb43e06 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
			     BASH PATCH REPORT
			     =================

Bash-Release: 3.1
Patch-ID: bash31-010

Bug-Reported-by: vw@vonwolff.de
Bug-Reference-ID: <20060123135234.1AC2F1D596@wst07.vonwolff.de>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2006-01/msg00090.html

Bug-Description:

There is a difference in behavior between bash-3.0 and bash-3.1 involving
parsing of single- and double-quoted strings occurring in old-style
command substitution.  The difference has to do with how backslashes are
processed.  This patch restores a measure of backwards compatibility while
the question of POSIX conformance and ultimately correct behavior is discussed.

THIS IS AN UPDATED PATCH.  USE THIS COMMAND TO REVERSE THE EFFECTS OF
THE ORIGINAL PATCH.  THE CURRENT DIRECTORY MUST BE THE BASH-3.1 SOURCE
DIRECTORY.

patch -p0 -R < bash31-010.orig

Then apply this patch as usual.

Patch:

*** bash-3.1/parse.y	Fri Nov 11 23:14:18 2005
--- bash-3.1/parse.y	Thu Feb 23 08:21:12 2006
***************
*** 2716,2721 ****
--- 2723,2729 ----
  #define P_ALLOWESC	0x02
  #define P_DQUOTE	0x04
  #define P_COMMAND	0x08	/* parsing a command, so look for comments */
+ #define P_BACKQUOTE	0x10	/* parsing a backquoted command substitution */
  
  static char matched_pair_error;
  static char *
***************
*** 2725,2736 ****
       int *lenp, flags;
  {
    int count, ch, was_dollar, in_comment, check_comment;
!   int pass_next_character, nestlen, ttranslen, start_lineno;
    char *ret, *nestret, *ttrans;
    int retind, retsize, rflags;
  
    count = 1;
!   pass_next_character = was_dollar = in_comment = 0;
    check_comment = (flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0;
  
    /* RFLAGS is the set of flags we want to pass to recursive calls. */
--- 2733,2744 ----
       int *lenp, flags;
  {
    int count, ch, was_dollar, in_comment, check_comment;
!   int pass_next_character, backq_backslash, nestlen, ttranslen, start_lineno;
    char *ret, *nestret, *ttrans;
    int retind, retsize, rflags;
  
    count = 1;
!   pass_next_character = backq_backslash = was_dollar = in_comment = 0;
    check_comment = (flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0;
  
    /* RFLAGS is the set of flags we want to pass to recursive calls. */
***************
*** 2742,2752 ****
    start_lineno = line_number;
    while (count)
      {
! #if 0
!       ch = shell_getc ((qc != '\'' || (flags & P_ALLOWESC)) && pass_next_character == 0);
! #else
!       ch = shell_getc (qc != '\'' && pass_next_character == 0);
! #endif
        if (ch == EOF)
  	{
  	  free (ret);
--- 2750,2757 ----
    start_lineno = line_number;
    while (count)
      {
!       ch = shell_getc (qc != '\'' && pass_next_character == 0 && backq_backslash == 0);
! 
        if (ch == EOF)
  	{
  	  free (ret);
***************
*** 2771,2779 ****
  	  continue;
  	}
        /* Not exactly right yet */
!       else if (check_comment && in_comment == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || whitespace (ret[retind -1])))
  	in_comment = 1;
  
        if (pass_next_character)		/* last char was backslash */
  	{
  	  pass_next_character = 0;
--- 2776,2791 ----
  	  continue;
  	}
        /* Not exactly right yet */
!       else if MBTEST(check_comment && in_comment == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || whitespace (ret[retind - 1])))
  	in_comment = 1;
  
+       /* last char was backslash inside backquoted command substitution */
+       if (backq_backslash)
+ 	{
+ 	  backq_backslash = 0;
+ 	  /* Placeholder for adding special characters */
+ 	}
+ 
        if (pass_next_character)		/* last char was backslash */
  	{
  	  pass_next_character = 0;
***************
*** 2814,2819 ****
--- 2824,2831 ----
  	{
  	  if MBTEST((flags & P_ALLOWESC) && ch == '\\')
  	    pass_next_character++;
+ 	  else if MBTEST((flags & P_BACKQUOTE) && ch == '\\')
+ 	    backq_backslash++;
  	  continue;
  	}
  
***************
*** 2898,2904 ****
  	}
        else if MBTEST(qc == '`' && (ch == '"' || ch == '\'') && in_comment == 0)
  	{
! 	  nestret = parse_matched_pair (0, ch, ch, &nestlen, rflags);
  	  goto add_nestret;
  	}
        else if MBTEST(was_dollar && (ch == '(' || ch == '{' || ch == '['))	/* ) } ] */
--- 2910,2920 ----
  	}
        else if MBTEST(qc == '`' && (ch == '"' || ch == '\'') && in_comment == 0)
  	{
! 	  /* Add P_BACKQUOTE so backslash quotes the next character and
! 	     shell_getc does the right thing with \<newline>.  We do this for
! 	     a measure  of backwards compatibility -- it's not strictly the
! 	     right POSIX thing. */
! 	  nestret = parse_matched_pair (0, ch, ch, &nestlen, rflags|P_BACKQUOTE);
  	  goto add_nestret;
  	}
        else if MBTEST(was_dollar && (ch == '(' || ch == '{' || ch == '['))	/* ) } ] */
*** bash-3.1/patchlevel.h	Wed Jul 20 13:58:20 2005
--- bash-3.1/patchlevel.h	Wed Dec  7 13:48:42 2005
***************
*** 26,30 ****
     looks for to find the patch level (for the sccs version string). */
  
! #define PATCHLEVEL 9
  
  #endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
     looks for to find the patch level (for the sccs version string). */
  
! #define PATCHLEVEL 10
  
  #endif /* _PATCHLEVEL_H_ */