Skip to content

Commit 0f2314f

Browse files
authored
initwd: require valid module name (#33745)
We install remote modules prior to showing any validation errors during init so that we can show errors about the core version requirement before we do anything else. Unfortunately, this means that we don't validate module names until after remote modules have been installed, which may cause unexpected problems if we can't convert the module name into a valid path.
1 parent 1c3e25b commit 0f2314f

File tree

4 files changed

+35
-1
lines changed

4 files changed

+35
-1
lines changed

internal/initwd/module_install.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
"github.com/apparentlymart/go-versions/versions"
1717
version "github.com/hashicorp/go-version"
1818
"github.com/hashicorp/hcl/v2"
19-
19+
"github.com/hashicorp/hcl/v2/hclsyntax"
2020
"github.com/hashicorp/terraform/internal/addrs"
2121
"github.com/hashicorp/terraform/internal/configs"
2222
"github.com/hashicorp/terraform/internal/configs/configload"
@@ -162,6 +162,13 @@ func (i *ModuleInstaller) moduleInstallWalker(ctx context.Context, manifest mods
162162
return nil, nil, diags
163163
}
164164

165+
if !hclsyntax.ValidIdentifier(req.Name) {
166+
// A module with an invalid name shouldn't be installed at all. This is
167+
// mostly a concern for remote modules, since we need to be able to convert
168+
// the name to a valid path.
169+
return nil, nil, diags
170+
}
171+
165172
key := manifest.ModuleKey(req.Path)
166173
instPath := i.packageInstallPath(req.Path)
167174

internal/initwd/module_install_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,27 @@ func TestModuleInstaller_emptyModuleName(t *testing.T) {
140140
}
141141
}
142142

143+
func TestModuleInstaller_invalidModuleName(t *testing.T) {
144+
fixtureDir := filepath.Clean("testdata/invalid-module-name")
145+
dir, done := tempChdir(t, fixtureDir)
146+
defer done()
147+
148+
hooks := &testInstallHooks{}
149+
150+
modulesDir := filepath.Join(dir, ".terraform/modules")
151+
152+
loader, close := configload.NewLoaderForTests(t)
153+
defer close()
154+
inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil))
155+
_, diags := inst.InstallModules(context.Background(), dir, "tests", false, false, hooks)
156+
157+
if !diags.HasErrors() {
158+
t.Fatal("expected error")
159+
} else {
160+
assertDiagnosticSummary(t, diags, "Invalid module instance name")
161+
}
162+
}
163+
143164
func TestModuleInstaller_packageEscapeError(t *testing.T) {
144165
fixtureDir := filepath.Clean("testdata/load-module-package-escape")
145166
dir, done := tempChdir(t, fixtureDir)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
output "boop" {
2+
value = "beep"
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module "../invalid" {
2+
source = "./child"
3+
}

0 commit comments

Comments
 (0)