Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

convert: Fix panic: heterogeneous tuple with null #56

Conversation

alisdair
Copy link
Contributor

@alisdair alisdair commented Jun 4, 2020

Tuples with elements of different types can be converted to homogeneous collections (sets or lists), so long as their elements are unifiable. For example:

toset(["a", "b"])     // all elements have the same type
toset(["a", 5])       // "a" and 5 can be unified to string
toset(["a", 5, null]) // null is a valid value for string

However, tuples with elements which are not unifiable cannot be converted to homogeneous collections:

toset([["a"], "b"])   // no common type for list(string) and string

This commit fixes a panic for this failure case, when the tuple contains both non-unifiable types and a null value:

toset([["a"], "b", null]) // should not panic

The null value was causing the unification process to result in a list or set of dynamic type, which causes the conversion functions to pass through the original value. This meant that in the final conversion step, we would attempt to construct a list or set of different values, which panics.

Fixes hashicorp/terraform#24377

Tuples with elements of different types can be converted to homogeneous
collections (sets or lists), so long as their elements are unifiable.
For example:

  list("a", "b")     // all elements have the same type
  list("a", 5)       // "a" and 5 can be unified to string
  list("a", 5, null) // null is a valid value for string

However, tuples with elements which are not unifiable cannot be
converted to homogeneous collections:

  list(["a"], "b")   // no common type for list(string) and string

This commit fixes a panic for this failure case, when the tuple contains
both non-unifiable types and a null value:

  list(["a"], "b", null) // should not panic

The null value was causing the unification process to result in a list
or set of dynamic type, which causes the conversion functions to pass
through the original value. This meant that in the final conversion
step, we would attempt to construct a list or set of different values,
which panics.
@codecov
Copy link

codecov bot commented Jun 4, 2020

Codecov Report

Merging #56 into master will increase coverage by 0.06%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #56      +/-   ##
==========================================
+ Coverage   70.54%   70.60%   +0.06%     
==========================================
  Files          79       79              
  Lines        7153     7161       +8     
==========================================
+ Hits         5046     5056      +10     
+ Misses       1664     1662       -2     
  Partials      443      443              
Impacted Files Coverage Δ
cty/convert/conversion_collection.go 82.79% <100.00%> (+1.24%) ⬆️
cty/convert/mismatch_msg.go 70.87% <0.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 07e6921...136299c. Read the comment docs.

Copy link
Contributor

@mildwonkey mildwonkey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice, that looked "fun" to figure out 😂

@@ -156,34 +156,45 @@ func conversionCollectionToMap(ety cty.Type, conv conversion) conversion {
// given tuple type and return a set of the given element type.
//
// Will panic if the given tupleType isn't actually a tuple type.
func conversionTupleToSet(tupleType cty.Type, listEty cty.Type, unsafe bool) conversion {
func conversionTupleToSet(tupleType cty.Type, setEty cty.Type, unsafe bool) conversion {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

excellent change, tyvm

Copy link
Collaborator

@apparentlymart apparentlymart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, nice! Thanks for digging into this. I have a memory of thinking something was a little off here when I originally wrote it but at the time I could quite get my head around it, but now you've pointed it out this makes perfect sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Terraform console crashes when passing incorrect arguments to setsubtract() function
3 participants