configs: Fix module loader nil pointer panic

In configurations which have already been initialized, updating the
source of a non-root module call to an invalid value could cause a nil
pointer panic. This commit fixes the bug and adds test coverage.
This commit is contained in:
Alisdair McDiarmid 2022-05-16 16:45:16 -04:00
parent 1fd140ff83
commit d1e35a3f7c
7 changed files with 37 additions and 3 deletions

View File

@ -60,8 +60,11 @@ func (l *Loader) moduleWalkerLoad(req *configs.ModuleRequest) (*configs.Module,
var diags hcl.Diagnostics
// Check for inconsistencies between manifest and config
if req.SourceAddr.String() != record.SourceAddr {
// Check for inconsistencies between manifest and config.
// We ignore a nil SourceAddr here, which represents a failure during
// configuration parsing, and will be reported in a diagnostic elsewhere.
if req.SourceAddr != nil && req.SourceAddr.String() != record.SourceAddr {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Module source has changed",

View File

@ -1,6 +1,7 @@
package configload
import (
"os"
"path/filepath"
"reflect"
"testing"
@ -71,6 +72,26 @@ module "child_b" {
}
func TestLoadConfigWithSnapshot_invalidSource(t *testing.T) {
fixtureDir := filepath.Clean("testdata/already-installed-now-invalid")
old, _ := os.Getwd()
os.Chdir(fixtureDir)
defer os.Chdir(old)
loader, err := NewLoader(&Config{
ModulesDir: ".terraform/modules",
})
if err != nil {
t.Fatalf("unexpected error from NewLoader: %s", err)
}
_, _, diags := loader.LoadConfigWithSnapshot(".")
if !diags.HasErrors() {
t.Error("LoadConfigWithSnapshot succeeded; want errors")
}
}
func TestSnapshotRoundtrip(t *testing.T) {
fixtureDir := filepath.Clean("testdata/already-installed")
loader, err := NewLoader(&Config{

View File

@ -14,7 +14,7 @@ func assertNoDiagnostics(t *testing.T, diags hcl.Diagnostics) bool {
func assertDiagnosticCount(t *testing.T, diags hcl.Diagnostics, want int) bool {
t.Helper()
if len(diags) != 0 {
if len(diags) != want {
t.Errorf("wrong number of diagnostics %d; want %d", len(diags), want)
for _, diag := range diags {
t.Logf("- %s", diag)

View File

@ -0,0 +1 @@
{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"foo","Source":"./foo","Dir":"foo"},{"Key":"foo.bar","Source":"./bar","Dir":"foo/bar"}]}

View File

@ -0,0 +1,3 @@
output "hello" {
value = "Hello from foo/bar"
}

View File

@ -0,0 +1,3 @@
module "bar" {
source = "${path.module}/bar"
}

View File

@ -0,0 +1,3 @@
module "foo" {
source = "./foo"
}