Skip to content

Commit fe70f0a

Browse files
authored
fix: prevent zero-byte remote state writes (#37947)
1 parent 869058f commit fe70f0a

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

internal/states/remote/remote_grpc.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,15 @@ func (g *grpcClient) Get() (*Payload, tfdiags.Diagnostics) {
7979
//
8080
// Implementation of remote.Client
8181
func (g *grpcClient) Put(state []byte) tfdiags.Diagnostics {
82+
if len(state) == 0 {
83+
var diags tfdiags.Diagnostics
84+
return diags.Append(tfdiags.Sourceless(
85+
tfdiags.Error,
86+
"Refusing to write empty remote state snapshot",
87+
"Terraform produced an empty state file and will not upload it to remote storage. This indicates a bug in Terraform; please report it.",
88+
))
89+
}
90+
8291
req := providers.WriteStateBytesRequest{
8392
TypeName: g.typeName,
8493
StateId: g.stateId,

internal/states/remote/remote_grpc_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,31 @@ func Test_grpcClient_Put(t *testing.T) {
221221
t.Fatalf("expected error to contain %q, but got: %s", expectedErr, err.Error())
222222
}
223223
})
224+
225+
t.Run("grpcClient refuses zero-byte writes", func(t *testing.T) {
226+
provider := testing_provider.MockProvider{
227+
ConfigureProviderCalled: true,
228+
ConfigureStateStoreCalled: true,
229+
WriteStateBytesFn: func(req providers.WriteStateBytesRequest) providers.WriteStateBytesResponse {
230+
t.Fatal("expected WriteStateBytes not to be called for zero-byte payload")
231+
return providers.WriteStateBytesResponse{}
232+
},
233+
}
234+
235+
client := &grpcClient{
236+
provider: &provider,
237+
typeName: typeName,
238+
stateId: stateId,
239+
}
240+
241+
diags := client.Put(nil)
242+
if !diags.HasErrors() {
243+
t.Fatalf("expected diagnostics when attempting to write zero bytes")
244+
}
245+
if provider.WriteStateBytesCalled {
246+
t.Fatalf("provider WriteStateBytes should not be called")
247+
}
248+
})
224249
}
225250

226251
// Testing grpcClient's Delete method.

0 commit comments

Comments
 (0)