Skip to content

Commit 721ca5d

Browse files
committed
internal/core/adt: fix panic due to envDisjunct corruption
We need to further investigate this, but this fix effectively makes envDisjunct data immutable once processing started, ensuring the integrity of the processing. Leaving open until we remove the TODO Issue #3857 Signed-off-by: Marcel van Lohuizen <[email protected]> Change-Id: I995294e280afee2302199e8599f97d17d9e80798 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1212383 Reviewed-by: Daniel Martí <[email protected]> TryBot-Result: CUEcueckoo <[email protected]>
1 parent 4fc579c commit 721ca5d

File tree

2 files changed

+388
-1
lines changed

2 files changed

+388
-1
lines changed

Diff for: cue/testdata/disjunctions/issue3857.txtar

+381
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,381 @@
1+
-- in.cue --
2+
reduced: t1: {
3+
S: { if true { a: U } }
4+
x: S
5+
x: {
6+
["a"]: b: 1 | T
7+
d: b: x.a
8+
}
9+
T: 1
10+
U: b: 1 | 1
11+
}
12+
issue3851: t1: {
13+
#Top: _
14+
#Config: {
15+
disj: _ | *"default"
16+
shared: _
17+
}
18+
19+
#Schema: {
20+
[string]: #Config
21+
if true {
22+
one: shared: "foo"
23+
}
24+
}
25+
26+
out: #Schema
27+
out: {
28+
["one"]: disj: _ | #Top
29+
two: shared: out.one.shared
30+
}
31+
}
32+
issue3851: t2: {
33+
#Top: _
34+
#Config: {
35+
disj: _ | *{}
36+
shared: _
37+
}
38+
39+
#Env: {
40+
conf: [string]: #Config
41+
if true {
42+
conf: one: shared: "foo"
43+
}
44+
}
45+
46+
env1: #Env
47+
48+
[string]: {
49+
conf: ["one"]: disj: {} | #Top
50+
conf: two: shared: conf.one.shared
51+
}
52+
}
53+
-- out/eval/stats --
54+
Leaks: 6
55+
Freed: 90
56+
Reused: 79
57+
Allocs: 17
58+
Retain: 2
59+
60+
Unifications: 60
61+
Conjuncts: 151
62+
Disjuncts: 98
63+
-- out/evalalpha --
64+
(struct){
65+
reduced: (struct){
66+
t1: (struct){
67+
S: (struct){
68+
a: ~(reduced.t1.U)
69+
}
70+
x: (struct){
71+
d: (struct){
72+
b: ~(reduced.t1.x.a)
73+
}
74+
a: (struct){
75+
b: (int){ 1 }
76+
}
77+
}
78+
T: (int){ 1 }
79+
U: (struct){
80+
b: (int){ 1 }
81+
}
82+
}
83+
}
84+
issue3851: (struct){
85+
t1: (struct){
86+
#Top: (_){ _ }
87+
#Config: (#struct){
88+
disj: (_){ |(*(string){ "default" }, (_){ _ }) }
89+
shared: (_){ _ }
90+
}
91+
#Schema: (#struct){
92+
one: (#struct){
93+
shared: (string){ "foo" }
94+
disj: (_){ |(*(string){ "default" }, (_){ _ }) }
95+
}
96+
}
97+
out: (#struct){
98+
two: (#struct){
99+
shared: (string){ "foo" }
100+
disj: (_){ |(*(string){ "default" }, (_){ _ }) }
101+
}
102+
one: (#struct){
103+
shared: (string){ "foo" }
104+
disj: (_){ _ }
105+
}
106+
}
107+
}
108+
t2: (struct){
109+
#Top: (_){ _ }
110+
#Config: (#struct){
111+
disj: (_){ |(*(#struct){
112+
}, (_){ _ }) }
113+
shared: (_){ _ }
114+
}
115+
#Env: (#struct){
116+
conf: (#struct){
117+
one: (#struct){
118+
shared: (string){ "foo" }
119+
disj: (_){ |(*(#struct){
120+
}, (_){ _ }) }
121+
}
122+
}
123+
}
124+
env1: (#struct){
125+
conf: (#struct){
126+
two: (#struct){
127+
shared: (string){ "foo" }
128+
disj: (_){ |(*(#struct){
129+
}, (_){ _ }) }
130+
}
131+
one: (#struct){
132+
shared: (string){ "foo" }
133+
disj: (_){ |(*(#struct){
134+
}, (_){ _ }, (#struct){
135+
}, (_){ _ }) }
136+
}
137+
}
138+
}
139+
}
140+
}
141+
}
142+
-- diff/-out/evalalpha<==>+out/eval --
143+
diff old new
144+
--- old
145+
+++ new
146+
@@ -2,18 +2,14 @@
147+
reduced: (struct){
148+
t1: (struct){
149+
S: (struct){
150+
- a: (struct){
151+
- b: (int){ 1 }
152+
- }
153+
+ a: ~(reduced.t1.U)
154+
}
155+
x: (struct){
156+
- a: (struct){
157+
- b: (int){ 1 }
158+
- }
159+
d: (struct){
160+
- b: (struct){
161+
- b: (int){ 1 }
162+
- }
163+
+ b: ~(reduced.t1.x.a)
164+
+ }
165+
+ a: (struct){
166+
+ b: (int){ 1 }
167+
}
168+
}
169+
T: (int){ 1 }
170+
@@ -36,14 +32,14 @@
171+
}
172+
}
173+
out: (#struct){
174+
- one: (#struct){
175+
- shared: (string){ "foo" }
176+
- disj: (_){ |(*(string){ "default" }, (_){ _ }) }
177+
- }
178+
two: (#struct){
179+
shared: (string){ "foo" }
180+
disj: (_){ |(*(string){ "default" }, (_){ _ }) }
181+
}
182+
+ one: (#struct){
183+
+ shared: (string){ "foo" }
184+
+ disj: (_){ _ }
185+
+ }
186+
}
187+
}
188+
t2: (struct){
189+
@@ -64,17 +60,17 @@
190+
}
191+
env1: (#struct){
192+
conf: (#struct){
193+
- one: (#struct){
194+
- shared: (string){ "foo" }
195+
- disj: (_){ |(*(#struct){
196+
- }, (_){ _ }, (struct){
197+
- }) }
198+
- }
199+
two: (#struct){
200+
shared: (string){ "foo" }
201+
disj: (_){ |(*(#struct){
202+
}, (_){ _ }) }
203+
}
204+
+ one: (#struct){
205+
+ shared: (string){ "foo" }
206+
+ disj: (_){ |(*(#struct){
207+
+ }, (_){ _ }, (#struct){
208+
+ }, (_){ _ }) }
209+
+ }
210+
}
211+
}
212+
}
213+
-- out/eval --
214+
(struct){
215+
reduced: (struct){
216+
t1: (struct){
217+
S: (struct){
218+
a: (struct){
219+
b: (int){ 1 }
220+
}
221+
}
222+
x: (struct){
223+
a: (struct){
224+
b: (int){ 1 }
225+
}
226+
d: (struct){
227+
b: (struct){
228+
b: (int){ 1 }
229+
}
230+
}
231+
}
232+
T: (int){ 1 }
233+
U: (struct){
234+
b: (int){ 1 }
235+
}
236+
}
237+
}
238+
issue3851: (struct){
239+
t1: (struct){
240+
#Top: (_){ _ }
241+
#Config: (#struct){
242+
disj: (_){ |(*(string){ "default" }, (_){ _ }) }
243+
shared: (_){ _ }
244+
}
245+
#Schema: (#struct){
246+
one: (#struct){
247+
shared: (string){ "foo" }
248+
disj: (_){ |(*(string){ "default" }, (_){ _ }) }
249+
}
250+
}
251+
out: (#struct){
252+
one: (#struct){
253+
shared: (string){ "foo" }
254+
disj: (_){ |(*(string){ "default" }, (_){ _ }) }
255+
}
256+
two: (#struct){
257+
shared: (string){ "foo" }
258+
disj: (_){ |(*(string){ "default" }, (_){ _ }) }
259+
}
260+
}
261+
}
262+
t2: (struct){
263+
#Top: (_){ _ }
264+
#Config: (#struct){
265+
disj: (_){ |(*(#struct){
266+
}, (_){ _ }) }
267+
shared: (_){ _ }
268+
}
269+
#Env: (#struct){
270+
conf: (#struct){
271+
one: (#struct){
272+
shared: (string){ "foo" }
273+
disj: (_){ |(*(#struct){
274+
}, (_){ _ }) }
275+
}
276+
}
277+
}
278+
env1: (#struct){
279+
conf: (#struct){
280+
one: (#struct){
281+
shared: (string){ "foo" }
282+
disj: (_){ |(*(#struct){
283+
}, (_){ _ }, (struct){
284+
}) }
285+
}
286+
two: (#struct){
287+
shared: (string){ "foo" }
288+
disj: (_){ |(*(#struct){
289+
}, (_){ _ }) }
290+
}
291+
}
292+
}
293+
}
294+
}
295+
}
296+
-- out/compile --
297+
--- in.cue
298+
{
299+
reduced: {
300+
t1: {
301+
S: {
302+
if true {
303+
a: 〈2;U〉
304+
}
305+
}
306+
x: 〈0;S〉
307+
x: {
308+
["a"]: {
309+
b: (1|〈2;T〉)
310+
}
311+
d: {
312+
b: 〈2;x〉.a
313+
}
314+
}
315+
T: 1
316+
U: {
317+
b: (1|1)
318+
}
319+
}
320+
}
321+
issue3851: {
322+
t1: {
323+
#Top: _
324+
#Config: {
325+
disj: (_|*"default")
326+
shared: _
327+
}
328+
#Schema: {
329+
[string]: 〈1;#Config〉
330+
if true {
331+
one: {
332+
shared: "foo"
333+
}
334+
}
335+
}
336+
out: 〈0;#Schema〉
337+
out: {
338+
["one"]: {
339+
disj: (_|〈2;#Top〉)
340+
}
341+
two: {
342+
shared: 〈2;out〉.one.shared
343+
}
344+
}
345+
}
346+
}
347+
issue3851: {
348+
t2: {
349+
#Top: _
350+
#Config: {
351+
disj: (_|*{})
352+
shared: _
353+
}
354+
#Env: {
355+
conf: {
356+
[string]: 〈2;#Config〉
357+
}
358+
if true {
359+
conf: {
360+
one: {
361+
shared: "foo"
362+
}
363+
}
364+
}
365+
}
366+
env1: 〈0;#Env〉
367+
[string]: {
368+
conf: {
369+
["one"]: {
370+
disj: ({}|〈3;#Top〉)
371+
}
372+
}
373+
conf: {
374+
two: {
375+
shared: 〈2;conf〉.one.shared
376+
}
377+
}
378+
}
379+
}
380+
}
381+
}

Diff for: internal/core/adt/disjunct2.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,13 @@ func (n *nodeContext) processDisjunctions() *Bottom {
374374

375375
// crossProduct computes the cross product of the disjuncts of a disjunction
376376
// with an existing set of results.
377-
func (n *nodeContext) crossProduct(dst, cross []*nodeContext, dn *envDisjunct, mode runMode) []*nodeContext {
377+
func (n *nodeContext) crossProduct(dst, cross []*nodeContext, dnp *envDisjunct, mode runMode) []*nodeContext {
378+
379+
// TODO: the envDisjunct may be overwritten with recursive calls to
380+
// disjunction processing. Investigate why this is. For now we copy the
381+
// value to make its state effectively immutable.
382+
dn := *dnp
383+
378384
defer n.unmarkDepth(n.markDepth())
379385
defer n.unmarkOptional(n.markOptional())
380386

0 commit comments

Comments
 (0)