Skip to content

Commit

Permalink
disallow explicit underscore import path qualifiers
Browse files Browse the repository at this point in the history
It is currently possible (and has been since pre CUE v0.4.3) to use an
explicit `_` import path qualifier to import packageless CUE files (as in
`foo.com/bar:_`), but this is unintentional. This change disallows it.

Some users have been using this as a "trick" to allow them to
load JSON files as CUE. The up-coming "embed" implementation (see
https://cuelang.org/issue/2031) should provide a sufficient alternative
solution.

Fixes #3167

Signed-off-by: Roger Peppe <rogpeppe@gmail.com>
Change-Id: Idfdec457961d4b144dfdd2890ea2e9887fc5a4dc
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1196721
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
  • Loading branch information
rogpeppe committed Jun 25, 2024
1 parent 5ab2d73 commit 1c381a0
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 12 deletions.
21 changes: 10 additions & 11 deletions cmd/cue/cmd/testdata/script/load_underscore.txtar
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
# Test whether an import with a _ qualifer is allowed or not.

# TODO(rog): this should fail; see https://cuelang.org/issue/3167
exec cue export ./foo
cmp stdout want-stdout
! exec cue export ./foo
cmp stderr want-stderr

# Check that it also fails with an explicit _ qualifier
# specified on the command line.
# TODO(rog): this should fail similarly.
exec cue export other.example/m:_
cmp stdout want-stdout
-- want-stdout --
{
"x": 20
}
# specified on the command line
! exec cue export other.example/m:_
cmp stderr want-stderr-2
-- want-stderr --
test.example/foo/foo@v0: import failed: cannot find package "other.example/m": _ is not a valid import path qualifier in "other.example/m:_":
./foo/foo.cue:8:8
-- want-stderr-2 --
invalid import path qualifier _ in "other.example/m:_"
-- cue.mod/gen/other.example/m/m.cue --
package _
x: 20
Expand Down
3 changes: 3 additions & 0 deletions cue/load/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,9 @@ func addImportQualifier(pkg importPath, name string) (importPath, error) {
return pkg, nil
}
ip := module.ParseImportPath(string(pkg))
if ip.Qualifier == "_" {
return "", fmt.Errorf("invalid import qualifier _ in %q", pkg)
}
if ip.ExplicitQualifier && ip.Qualifier != name {
return "", fmt.Errorf("non-matching package names (%s != %s)", ip.Qualifier, name)
}
Expand Down
2 changes: 2 additions & 0 deletions cue/load/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@ func (l *loader) newInstance(pos token.Pos, p importPath) *build.Instance {
i.PkgName = parts.Qualifier
if i.PkgName == "" {
i.Err = errors.Append(i.Err, l.errPkgf([]token.Pos{pos}, "cannot determine package name for %q; set it explicitly with ':'", p))
} else if i.PkgName == "" {
i.Err = errors.Append(i.Err, l.errPkgf([]token.Pos{pos}, "_ is not a valid import path qualifier in %q", p))
}
i.DisplayPath = string(p)
i.ImportPath = string(p)
Expand Down
3 changes: 3 additions & 0 deletions cue/load/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,9 @@ func appendExpandedPackageArg(c *Config, pkgPaths []resolvedPackageArg, p string
p = filepath.ToSlash(p)

ip := module.ParseImportPath(p)
if ip.Qualifier == "_" {
return nil, fmt.Errorf("invalid import path qualifier _ in %q", origp)
}

isRel := strings.HasPrefix(ip.Path, "./")
// Put argument in canonical form.
Expand Down
4 changes: 4 additions & 0 deletions internal/mod/modpkgload/pkgload.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ func (pkgs *Packages) load(ctx context.Context, pkg *Package) {
pkg.err = fmt.Errorf("cannot determine package name from import path %q", pkg.path)
return
}
if pkgQual == "_" {
pkg.err = fmt.Errorf("_ is not a valid import path qualifier in %q", pkg.path)
return
}
importsMap := make(map[string]bool)
foundPackageFile := false
for _, loc := range pkg.locs {
Expand Down
2 changes: 1 addition & 1 deletion mod/module/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ func ParseImportPath(p string) ImportPath {
} else {
parts.Qualifier = parts.Path
}
if !ast.IsValidIdent(parts.Qualifier) || strings.HasPrefix(parts.Qualifier, "#") {
if !ast.IsValidIdent(parts.Qualifier) || strings.HasPrefix(parts.Qualifier, "#") || parts.Qualifier == "_" {
parts.Qualifier = ""
}
}
Expand Down

0 comments on commit 1c381a0

Please sign in to comment.