hashicorp / terraform-plugin-sdk

Terraform Plugin SDK enables building plugins (providers) to manage any service providers or custom in-house solutions

Home Page:https://developer.hashicorp.com/terraform/plugin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

losing precision when using maximum value for a 64-bit signed integer

Serpentiel opened this issue · comments

SDK version

latest

Relevant provider source code

Terraform reads it correctly in first place, until it reaches grpc_provider.go, here is an example where it's read properly:

image

then in grpc_provider.go this code makes it lose its precision:

newStateVal, err := hcl2shim.HCL2ValueFromFlatmap(newInstanceState.Attributes, schemaBlock.ImpliedType())
if err != nil {
	resp.Diagnostics = convert.AppendProtoDiag(ctx, resp.Diagnostics, err)
	return resp, nil
}

here's what debugger shows:

image

and if you convert it to string or float64 by calling big.Float's relevant methods, it becomes wrong:

image

newStateVal then doesn't have the correct data stored for the field that had 9223372036854775807 as its value, instead it has 9223372036854776000 which leads to the crash:

panic: Error reading level state: strconv.ParseInt: parsing "9223372036854776000": value out of range

goroutine 79 [running]:
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*ResourceData).get(0xc0000fd000, {0xc000ac7720, 0x1, 0x1}, 0x8?)
        github.com/hashicorp/terraform-plugin-sdk/v2@v2.26.1/helper/schema/resource_data.go:553 +0x328
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*ResourceData).State(0xc0000fd000)
        github.com/hashicorp/terraform-plugin-sdk/v2@v2.26.1/helper/schema/resource_data.go:351 +0x393
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).ShimInstanceStateFromValue(0xc0007a89a0, {{{0xf528e0?, 0xc00000e9f0?}}, {0xcea680?, 0xc00031d680?}})
        github.com/hashicorp/terraform-plugin-sdk/v2@v2.26.1/helper/schema/resource.go:599 +0x1c9
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).ReadResource(0xc0001861b0, {0xf521e0?, 0xc0007dcf90?}, 0xc0006b05c0)
        github.com/hashicorp/terraform-plugin-sdk/v2@v2.26.1/helper/schema/grpc_provider.go:587 +0x205
github.com/hashicorp/terraform-plugin-mux/tf5to6server.v5tov6Server.ReadResource({{0xf55798?, 0xc0001861b0?}}, {0xf521e0?, 0xc0007dcf90?}, 0xc0006b0440?)
        github.com/hashicorp/terraform-plugin-mux@v0.10.0/tf5to6server/tf5to6server.go:105 +0x242
github.com/hashicorp/terraform-plugin-mux/tf6muxserver.muxServer.ReadResource({0xc0007ddb00, 0xc0007ddb60, {0xc00082f1f0, 0x1, 0x1}, {0x0, 0x0, 0x0}, {0x0, 0x0, ...}, ...}, ...)
        github.com/hashicorp/terraform-plugin-mux@v0.10.0/tf6muxserver/mux_server_ReadResource.go:26 +0x102
github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server.(*server).ReadResource(0xc0000caf00, {0xf521e0?, 0xc0002d8780?}, 0xc00070c600)
        github.com/hashicorp/terraform-plugin-go@v0.15.0/tfprotov6/tf6server/server.go:746 +0x49e
github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6._Provider_ReadResource_Handler({0xdac4c0?, 0xc0000caf00}, {0xf521e0, 0xc0002d8780}, 0xc000282000, 0x0)
        github.com/hashicorp/terraform-plugin-go@v0.15.0/tfprotov6/internal/tfplugin6/tfplugin6_grpc.pb.go:383 +0x170
google.golang.org/grpc.(*Server).processUnaryRPC(0xc0000001e0, {0xf55000, 0xc0007da4e0}, 0xc000828360, 0xc0006c1a40, 0x14b2d10, 0x0)
        google.golang.org/grpc@v1.54.0/server.go:1345 +0xde3
google.golang.org/grpc.(*Server).handleStream(0xc0000001e0, {0xf55000, 0xc0007da4e0}, 0xc000828360, 0x0)
        google.golang.org/grpc@v1.54.0/server.go:1722 +0xa1b
google.golang.org/grpc.(*Server).serveStreams.func1.2()
        google.golang.org/grpc@v1.54.0/server.go:966 +0x98
created by google.golang.org/grpc.(*Server).serveStreams.func1
        google.golang.org/grpc@v1.54.0/server.go:964 +0x28a

Expected Behavior

it should have worked properly and returned 9223372036854775807 instead

Actual Behavior

it returns 9223372036854776000

Steps to Reproduce

  • add a numeric field
  • fill it with 9223372036854775807
  • Terraform is going to crash when attempting to read this resource from the state

N.B. it only crashes when it's read after it's already created, i.e. during resource's creation—it won't fail

References