Skip to content

Commit 5e017a4

Browse files
notJoonthehowl
andauthored
feat(cmd): gno mod module name validations (#3526)
# Description closes #3493 Added module path validation to prevent invalid characters from being written to `gno mod` parsing phase. The validation: 1. Checks for non-ASCII characters 2. Validates against specific invalid characters (``, ", \, ?, *, :, <, >, |, [, ]`) 3. Prevents spaces and control characters 4. Ensures the module path is not empty --------- Co-authored-by: Morgan Bazalgette <[email protected]>
1 parent a53c05d commit 5e017a4

File tree

2 files changed

+96
-1
lines changed

2 files changed

+96
-1
lines changed

gnovm/pkg/gnomod/parse.go

+4
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ func (f *File) add(errs *modfile.ErrorList, block *modfile.LineBlock, line *modf
178178
errorf("invalid quoted string: %v", err)
179179
return
180180
}
181+
if err := module.CheckImportPath(s); err != nil {
182+
errorf("invalid module path: %v", err)
183+
return
184+
}
181185
f.Module.Mod = module.Version{Path: s}
182186

183187
case "replace":

gnovm/pkg/gnomod/parse_test.go

+92-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func TestModuleDeprecated(t *testing.T) {
8181
{
8282
desc: "deprecated_paragraph_space",
8383
in: `// Deprecated: the next line has a space
84-
//
84+
//
8585
// c
8686
module m`,
8787
expected: "the next line has a space",
@@ -237,3 +237,94 @@ func TestParseGnoMod(t *testing.T) {
237237
})
238238
}
239239
}
240+
241+
// TestParseWithInvalidModulePath tests that Parse correctly rejects gno.mod files
242+
// with invalid module paths.
243+
func TestParseWithInvalidModulePath(t *testing.T) {
244+
tests := []struct {
245+
name string
246+
modData string
247+
errMsg string
248+
}{
249+
{
250+
name: "valid module path",
251+
modData: "module gno.land/p/demo/foo",
252+
errMsg: "",
253+
},
254+
{
255+
name: "module path with space",
256+
modData: "module \"gno.land/p/demo/ foo\"",
257+
errMsg: "malformed import path \"gno.land/p/demo/ foo\": invalid char ' '",
258+
},
259+
{
260+
name: "module path with Unicode",
261+
modData: "module gno.land/p/demo/한글",
262+
errMsg: "malformed import path \"gno.land/p/demo/한글\": invalid char '한'",
263+
},
264+
{
265+
name: "module path with invalid character",
266+
modData: "module gno.land/p/demo/foo*bar",
267+
errMsg: "malformed import path \"gno.land/p/demo/foo*bar\": invalid char '*'",
268+
},
269+
}
270+
271+
for _, tt := range tests {
272+
t.Run(tt.name, func(t *testing.T) {
273+
_, err := Parse("gno.mod", []byte(tt.modData))
274+
if tt.errMsg != "" {
275+
assert.Error(t, err)
276+
assert.Contains(t, err.Error(), tt.errMsg)
277+
} else {
278+
assert.NoError(t, err)
279+
}
280+
})
281+
}
282+
}
283+
284+
// TestCreateGnoModFileWithInvalidPath tests that CreateGnoModFile correctly rejects
285+
// invalid module paths.
286+
func TestCreateGnoModFileWithInvalidPath(t *testing.T) {
287+
tests := []struct {
288+
name string
289+
modPath string
290+
errMsg string
291+
}{
292+
{
293+
name: "valid module path",
294+
modPath: "gno.land/p/demo/foo",
295+
errMsg: "",
296+
},
297+
{
298+
name: "module path with space",
299+
modPath: "gno.land/p/demo/ foo",
300+
errMsg: "malformed import path \"gno.land/p/demo/ foo\": invalid char ' '",
301+
},
302+
{
303+
name: "module path with Unicode",
304+
modPath: "gno.land/p/demo/한글",
305+
errMsg: "malformed import path \"gno.land/p/demo/한글\": invalid char '한'",
306+
},
307+
{
308+
name: "module path with invalid character",
309+
modPath: "gno.land/p/demo/foo*bar",
310+
errMsg: "malformed import path \"gno.land/p/demo/foo*bar\": invalid char '*'",
311+
},
312+
}
313+
314+
for _, tt := range tests {
315+
t.Run(tt.name, func(t *testing.T) {
316+
tempDir, cleanUpFn := testutils.NewTestCaseDir(t)
317+
defer cleanUpFn()
318+
319+
err := CreateGnoModFile(tempDir, tt.modPath)
320+
if tt.errMsg != "" {
321+
assert.Error(t, err)
322+
assert.Contains(t, err.Error(), tt.errMsg)
323+
} else {
324+
if err != nil && !assert.Contains(t, err.Error(), "dir") {
325+
t.Errorf("unexpected error: %v", err)
326+
}
327+
}
328+
})
329+
}
330+
}

0 commit comments

Comments
 (0)