Skip to content

Commit

Permalink
cue/interpreter/embed: forbid ** via pkg/path.Match
Browse files Browse the repository at this point in the history
Our pkg/path.Match func mimics Go's own path.Match in that it can be
used as a validator via `Match(pattern, "")`. This is better than a
`strings.Contains(pattern, "**")` not only because we get consistent
error messages, but also because Contains gives false positives
on valid patterns such as `\**`, which escapes the first star,
or `[x**y]`, where the stars are just part of a character set.

Fix the code, and add more tests that demonstrate that embedding
does support a glob with `\**` now.

This brings embed in line with pkg/path.Match and tool/file.Glob
in terms of what pattern matching syntax and features it supports.

Signed-off-by: Daniel Martí <[email protected]>
Change-Id: I0ed6fcab9426c6392fb18491a3f656f29c56b41e
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1198692
Reviewed-by: Roger Peppe <[email protected]>
Unity-Result: CUE porcuepine <[email protected]>
TryBot-Result: CUEcueckoo <[email protected]>
  • Loading branch information
mvdan committed Jul 31, 2024
1 parent 987a85e commit 187fb1a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
2 changes: 1 addition & 1 deletion cmd/cue/cmd/testdata/script/embed_err.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ language: version: "v0.9.0"
./test.cue:19:15
@embed: only relative files are allowed:
./test.cue:21:12
@embed: double star not (yet) supported in glob:
@embed: invalid glob pattern "**/*.json": '**' is not supported in patterns as of yet:
./test.cue:23:15
@embed: streaming not implemented: found more than one value in file:
./test.cue:25:11
Expand Down
33 changes: 33 additions & 0 deletions cmd/cue/cmd/testdata/script/embed_windows.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
env CUE_EXPERIMENT=embed

[!windows] cp reuse.json 'star/*.json'
[!windows] exec cue export --out cue
[!windows] cmp stdout out/export-unix

[windows] exec cue export --out cue
[windows] cmp stdout out/export-windows

-- test.cue --
@extern(embed)

package foo

// Unix OSes can have a file containing a star character, and we can match it.
// Windows can still use these file paths and glob patterns, but they can't match
// a file containing a star character, as such filenames are not allowed on Windows.

globStar: _ @embed(glob="star/*.json")
globEscapeStar: _ @embed(glob="star/\\**", type=json)
-- reuse.json --
{"x": "to be reused for more names"}
-- star/simple.json --
{"x": "does not contain a star character"}
-- out/export-unix --
globStar: {
"star/*.json": x: "to be reused for more names"
"star/simple.json": x: "does not contain a star character"
}
globEscapeStar: "star/*.json": x: "to be reused for more names"
-- out/export-windows --
globStar: "star/simple.json": x: "does not contain a star character"
globEscapeStar: {}
7 changes: 5 additions & 2 deletions cue/interpreter/embed/embed.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ import (
"cuelang.org/go/internal/encoding"
"cuelang.org/go/internal/filetypes"
"cuelang.org/go/internal/value"
pkgpath "cuelang.org/go/pkg/path"
)

// TODO: obtain a fs.FS from load or something similar
Expand Down Expand Up @@ -218,8 +219,10 @@ func (c *compiler) processGlob(glob, scope string, schema adt.Value) (adt.Expr,
return nil, ce
}

if strings.Contains(glob, "**") {
return nil, errors.Newf(c.pos, "double star not (yet) supported in glob")
// Validate that the glob pattern is valid per [pkgpath.Match].
// Note that we use Unix match semantics because all embed paths are Unix-like.
if _, err := pkgpath.Match(glob, "", pkgpath.Unix); err != nil {
return nil, errors.Wrapf(err, c.pos, "invalid glob pattern %q", glob)
}

// If we do not have a type, ensure the extension of the base is fully
Expand Down

0 comments on commit 187fb1a

Please sign in to comment.