-
Notifications
You must be signed in to change notification settings - Fork 7
/
make-4.4.1-SV49841.patch
206 lines (186 loc) · 7.04 KB
/
make-4.4.1-SV49841.patch
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
--- make-4.4.1-orig/src/expand.c 2023-01-28 18:18:16.000000000 +0300
+++ make-4.4.1/src/expand.c 2024-09-18 09:08:36.590934500 +0300
@@ -521,7 +538,7 @@
return initialize_variable_output ();
/* If this set is local and the next is not a parent, then next is local. */
- nextlocal = local && set->next_is_parent == 0;
+ nextlocal = local && set->mark != NEXT_IS_PARENT;
/* Try to find the variable in this variable set. */
v = lookup_variable_in_set (name, length, set->set);
--- make-4.4.1-orig/src/function.c 2023-01-12 03:51:34.000000000 +0300
+++ make-4.4.1/src/function.c 2024-09-18 09:23:10.970908100 +0300
@@ -2718,6 +2718,7 @@
int saved_args;
const struct function_table_entry *entry_p;
struct variable *v;
+ struct variable_set_list *setlist;
/* Clean up the name of the variable to be invoked. */
fname = next_token (argv[0]);
@@ -2759,7 +2760,7 @@
/* Set up arguments $(1) .. $(N). $(0) is the function name. */
- push_new_variable_scope ();
+ setlist = push_new_variable_scope ();
for (i=0; *argv; ++i, ++argv)
{
@@ -2769,26 +2770,23 @@
define_variable (num, strlen (num), *argv, o_automatic, 0);
}
- /* If the number of arguments we have is < max_args, it means we're inside
- a recursive invocation of $(call ...). Fill in the remaining arguments
- in the new scope with the empty value, to hide them from this
- invocation. */
-
- for (; i < max_args; ++i)
- {
- char num[INTSTR_LENGTH];
+ /* Adjust max_args - the maximum number of arguments among calls of
+ user-defined functions in the call stack up to and including this
+ $(call ...) invocation. */
+ saved_args = max_args;
+ if (i > max_args)
+ max_args = i;
- sprintf (num, "%u", i);
- define_variable (num, strlen (num), "", o_automatic, 0);
- }
+ /* Mark the list with max_args - the mark is checked while looking up
+ variables in outer scope: if variable name looks like a user-defined
+ function call argument, e.g. $(123), and it's decimal value is less
+ than the mark, then the variable must not be found. */
+ setlist->mark = max_args;
/* Expand the body in the context of the arguments, adding the result to
the variable buffer. */
v->exp_count = EXP_COUNT_MAX;
-
- saved_args = max_args;
- max_args = i;
o = variable_expand_string (o, body, flen+3);
max_args = saved_args;
--- make-4.4.1-orig/src/variable.c 2023-01-28 21:04:47.000000000 +0300
+++ make-4.4.1/src/variable.c 2024-09-18 12:13:23.564922300 +0300
@@ -462,6 +462,7 @@
const struct variable_set_list *setlist;
struct variable var_key;
int is_parent = 0;
+ int maybe_argument = 1;
var_key.name = (char *) name;
var_key.length = (unsigned int) length;
@@ -476,7 +477,45 @@
if (v && (!is_parent || !v->private_var))
return v->special ? lookup_special_var (v) : v;
- is_parent |= setlist->next_is_parent;
+ /* Variable was not found. Check if it looks like a function call
+ argument: $1,$2,$3... If it is and we are in the context of user
+ function call, then we must not take arguments of outer functions. */
+
+ if (setlist->mark == NEXT_IS_PARENT)
+ is_parent = 1;
+ else if (setlist->mark && maybe_argument)
+ {
+ /* Argument $0 is always defined and must be found,
+ names of other arguments do not begin with '0' */
+ if ('0' != *name)
+ {
+ /* Try to parse decimal number. Check for integer overflow.
+ If parsing failed or the number is greater or equal to the
+ maximum number of arguments among calls of user-defined
+ functions in the call stack, then the variable is not a
+ function argument. */
+ int number = 0, a;
+ const int m = setlist->mark/10;
+ size_t i;
+ for (i = 0; i < length; i++)
+ {
+ if (!ISDIGIT(name[i]))
+ break;
+ if (number > m)
+ break;
+ number *= 10;
+ a = name[i] - '0';
+ if (a >= setlist->mark - number)
+ break;
+ number += a;
+ }
+
+ if (i == length)
+ return 0;
+ }
+
+ maybe_argument = 0;
+ }
}
#ifdef VMS
@@ -611,7 +650,7 @@
{
initialize_file_variables (file->double_colon, reading);
l->next = file->double_colon->variables;
- l->next_is_parent = 0;
+ l->mark = 0;
return;
}
@@ -622,7 +661,7 @@
initialize_file_variables (file->parent, reading);
l->next = file->parent->variables;
}
- l->next_is_parent = 1;
+ l->mark = NEXT_IS_PARENT;
/* If we're not reading makefiles and we haven't looked yet, see if
we can find pattern variables for this target. */
@@ -683,9 +722,9 @@
if (file->pat_variables != 0)
{
file->pat_variables->next = l->next;
- file->pat_variables->next_is_parent = l->next_is_parent;
+ file->pat_variables->mark = l->mark;
l->next = file->pat_variables;
- l->next_is_parent = 0;
+ l->mark = 0;
}
}
@@ -706,7 +745,7 @@
xmalloc (sizeof (struct variable_set_list));
setlist->set = set;
setlist->next = current_variable_set_list;
- setlist->next_is_parent = 0;
+ setlist->mark = 0;
return setlist;
}
@@ -730,7 +769,9 @@
current_variable_set_list->set = global_setlist.set;
global_setlist.set = set;
current_variable_set_list->next = global_setlist.next;
+ current_variable_set_list->mark = global_setlist.mark;
global_setlist.next = current_variable_set_list;
+ global_setlist.mark = 0;
current_variable_set_list = &global_setlist;
}
return (current_variable_set_list);
@@ -761,7 +802,7 @@
set = global_setlist.set;
global_setlist.set = setlist->set;
global_setlist.next = setlist->next;
- global_setlist.next_is_parent = setlist->next_is_parent;
+ global_setlist.mark = setlist->mark;
}
/* Free the one we no longer need. */
--- make-4.4.1-orig/src/variable.h 2023-01-28 21:04:47.000000000 +0300
+++ make-4.4.1/src/variable.h 2024-09-18 08:57:33.459838100 +0300
@@ -100,7 +100,19 @@
{
struct variable_set_list *next; /* Link in the chain. */
struct variable_set *set; /* Variable set. */
- int next_is_parent; /* True if next is a parent target. */
+
+ /* Mark of the list:
+ -1 - next is a parent target;
+ 0 - list is not marked;
+ >0 - variable set of the list contains arguments of user-defined function
+ call. Mark value - is the maximum number of arguments among calls
+ of user-defined functions in the call stack up to and including this
+ list. Function name (passed as $0 argument) is always counted, so
+ number of arguments cannot be zero. */
+
+#define NEXT_IS_PARENT -1
+
+ int mark;
};
/* Structure used for pattern-specific variables. */