Skip to content

Commit

Permalink
pass all marks through conditional expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
jbardin committed Nov 14, 2024
1 parent d20d07f commit bbfec2d
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 18 deletions.
31 changes: 16 additions & 15 deletions hclsyntax/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -788,21 +788,24 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
})
return cty.UnknownVal(resultType), diags
}
if !condResult.IsKnown() {
// we use the unmarked values throughout the unknown branch
_, condResultMarks := condResult.Unmark()
trueResult, trueResultMarks := trueResult.Unmark()
falseResult, falseResultMarks := falseResult.Unmark()

// use a value to merge marks
_, resMarks := cty.DynamicVal.WithMarks(condResultMarks, trueResultMarks, falseResultMarks).Unmark()
// Now that we have all three values, collect all the marks for the result.
// Since it's possible that a condition value could be unknown, and the
// consumer needs to deal with any marks from either branch anyway, we must
// always combine them for consistent results.
condResult, condResultMarks := condResult.Unmark()
trueResult, trueResultMarks := trueResult.Unmark()
falseResult, falseResultMarks := falseResult.Unmark()
var resMarks []cty.ValueMarks
resMarks = append(resMarks, condResultMarks, trueResultMarks, falseResultMarks)

if !condResult.IsKnown() {
trueRange := trueResult.Range()
falseRange := falseResult.Range()

// if both branches are known to be null, then the result must still be null
if trueResult.IsNull() && falseResult.IsNull() {
return cty.NullVal(resultType).WithMarks(resMarks), diags
return cty.NullVal(resultType).WithMarks(resMarks...), diags
}

// We might be able to offer a refined range for the result based on
Expand Down Expand Up @@ -841,7 +844,7 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
ref = ref.NumberRangeUpperBound(hi, hiInc)
}

return ref.NewValue().WithMarks(resMarks), diags
return ref.NewValue().WithMarks(resMarks...), diags
}

if trueResult.Type().IsCollectionType() && falseResult.Type().IsCollectionType() {
Expand All @@ -867,15 +870,15 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
}

ref = ref.CollectionLengthLowerBound(lo).CollectionLengthUpperBound(hi)
return ref.NewValue().WithMarks(resMarks), diags
return ref.NewValue().WithMarks(resMarks...), diags
}
}

ret := cty.UnknownVal(resultType)
if trueRange.DefinitelyNotNull() && falseRange.DefinitelyNotNull() {
ret = ret.RefineNotNull()
}
return ret.WithMarks(resMarks), diags
return ret.WithMarks(resMarks...), diags
}

condResult, err := convert.Convert(condResult, cty.Bool)
Expand All @@ -892,8 +895,6 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
return cty.UnknownVal(resultType), diags
}

// Unmark result before testing for truthiness
condResult, _ = condResult.UnmarkDeep()
if condResult.True() {
diags = append(diags, trueDiags...)
if convs[0] != nil {
Expand All @@ -916,7 +917,7 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
trueResult = cty.UnknownVal(resultType)
}
}
return trueResult, diags
return trueResult.WithMarks(resMarks...), diags
} else {
diags = append(diags, falseDiags...)
if convs[1] != nil {
Expand All @@ -939,7 +940,7 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
falseResult = cty.UnknownVal(resultType)
}
}
return falseResult, diags
return falseResult.WithMarks(resMarks...), diags
}
}

Expand Down
4 changes: 2 additions & 2 deletions hclsyntax/expression_template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,14 +318,14 @@ trim`,
cty.UnknownVal(cty.String).Refine().NotNull().StringPrefixFull(strings.Repeat("_", 128)).NewValue(),
0,
},
{ // marks from uninterpolated values are ignored
{ // all marks are passed through to ensure result is always consistent
`hello%{ if false } ${target}%{ endif }`,
&hcl.EvalContext{
Variables: map[string]cty.Value{
"target": cty.StringVal("world").Mark("sensitive"),
},
},
cty.StringVal("hello"),
cty.StringVal("hello").Mark("sensitive"),
0,
},
{ // marks from interpolated values are passed through
Expand Down
2 changes: 1 addition & 1 deletion hclsyntax/expression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2175,7 +2175,7 @@ EOT
}).Mark("sensitive"),
},
},
cty.NumberIntVal(1),
cty.NumberIntVal(1).Mark("sensitive"),
0,
},
{ // auto-converts collection types
Expand Down

0 comments on commit bbfec2d

Please sign in to comment.