Merge "Only allow .scl files to load other .scl files" into main
This commit is contained in:
@@ -31,11 +31,11 @@ import (
|
|||||||
type ExecutionMode int
|
type ExecutionMode int
|
||||||
const (
|
const (
|
||||||
ExecutionModeRbc ExecutionMode = iota
|
ExecutionModeRbc ExecutionMode = iota
|
||||||
ExecutionModeMake ExecutionMode = iota
|
ExecutionModeScl ExecutionMode = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
const allowExternalEntrypointKey = "allowExternalEntrypoint"
|
const allowExternalEntrypointKey = "allowExternalEntrypoint"
|
||||||
const callerDirKey = "callerDir"
|
const callingFileKey = "callingFile"
|
||||||
const executionModeKey = "executionMode"
|
const executionModeKey = "executionMode"
|
||||||
const shellKey = "shell"
|
const shellKey = "shell"
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ var rbcBuiltins starlark.StringDict = starlark.StringDict{
|
|||||||
"rblf_wildcard": starlark.NewBuiltin("rblf_wildcard", wildcard),
|
"rblf_wildcard": starlark.NewBuiltin("rblf_wildcard", wildcard),
|
||||||
}
|
}
|
||||||
|
|
||||||
var makeBuiltins starlark.StringDict = starlark.StringDict{
|
var sclBuiltins starlark.StringDict = starlark.StringDict{
|
||||||
"struct": starlark.NewBuiltin("struct", starlarkstruct.Make),
|
"struct": starlark.NewBuiltin("struct", starlarkstruct.Make),
|
||||||
"json": starlarkjson.Module,
|
"json": starlarkjson.Module,
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,8 @@ func loader(thread *starlark.Thread, module string) (starlark.StringDict, error)
|
|||||||
module = module[:pipePos]
|
module = module[:pipePos]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
modulePath, err := cleanModuleName(module, thread.Local(callerDirKey).(string), allowExternalEntrypoint)
|
callingFile := thread.Local(callingFileKey).(string)
|
||||||
|
modulePath, err := cleanModuleName(module, filepath.Dir(callingFile), allowExternalEntrypoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -150,6 +151,13 @@ func loader(thread *starlark.Thread, module string) (starlark.StringDict, error)
|
|||||||
|
|
||||||
// Load or return default
|
// Load or return default
|
||||||
if mustLoad {
|
if mustLoad {
|
||||||
|
if strings.HasSuffix(callingFile, ".scl") && !strings.HasSuffix(modulePath, ".scl") {
|
||||||
|
return nil, fmt.Errorf(".scl files can only load other .scl files: %q loads %q", callingFile, modulePath)
|
||||||
|
}
|
||||||
|
// Switch into scl mode from here on
|
||||||
|
if strings.HasSuffix(modulePath, ".scl") {
|
||||||
|
mode = ExecutionModeScl
|
||||||
|
}
|
||||||
childThread := &starlark.Thread{Name: "exec " + module, Load: thread.Load}
|
childThread := &starlark.Thread{Name: "exec " + module, Load: thread.Load}
|
||||||
// Cheating for the sake of testing:
|
// Cheating for the sake of testing:
|
||||||
// propagate starlarktest's Reporter key, otherwise testing
|
// propagate starlarktest's Reporter key, otherwise testing
|
||||||
@@ -161,14 +169,14 @@ func loader(thread *starlark.Thread, module string) (starlark.StringDict, error)
|
|||||||
|
|
||||||
// Only the entrypoint starlark file allows external loads.
|
// Only the entrypoint starlark file allows external loads.
|
||||||
childThread.SetLocal(allowExternalEntrypointKey, false)
|
childThread.SetLocal(allowExternalEntrypointKey, false)
|
||||||
childThread.SetLocal(callerDirKey, filepath.Dir(modulePath))
|
childThread.SetLocal(callingFileKey, modulePath)
|
||||||
childThread.SetLocal(executionModeKey, mode)
|
childThread.SetLocal(executionModeKey, mode)
|
||||||
childThread.SetLocal(shellKey, thread.Local(shellKey))
|
childThread.SetLocal(shellKey, thread.Local(shellKey))
|
||||||
if mode == ExecutionModeRbc {
|
if mode == ExecutionModeRbc {
|
||||||
globals, err := starlark.ExecFile(childThread, modulePath, nil, rbcBuiltins)
|
globals, err := starlark.ExecFile(childThread, modulePath, nil, rbcBuiltins)
|
||||||
e = &modentry{globals, err}
|
e = &modentry{globals, err}
|
||||||
} else if mode == ExecutionModeMake {
|
} else if mode == ExecutionModeScl {
|
||||||
globals, err := starlark.ExecFile(childThread, modulePath, nil, makeBuiltins)
|
globals, err := starlark.ExecFile(childThread, modulePath, nil, sclBuiltins)
|
||||||
e = &modentry{globals, err}
|
e = &modentry{globals, err}
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("unknown executionMode %d", mode)
|
return nil, fmt.Errorf("unknown executionMode %d", mode)
|
||||||
@@ -338,7 +346,7 @@ func Run(filename string, src interface{}, mode ExecutionMode, allowExternalEntr
|
|||||||
if mode == ExecutionModeRbc {
|
if mode == ExecutionModeRbc {
|
||||||
// In rbc mode, rblf_log is used to print to stderr
|
// In rbc mode, rblf_log is used to print to stderr
|
||||||
fmt.Println(msg)
|
fmt.Println(msg)
|
||||||
} else if mode == ExecutionModeMake {
|
} else if mode == ExecutionModeScl {
|
||||||
fmt.Fprintln(os.Stderr, msg)
|
fmt.Fprintln(os.Stderr, msg)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -365,13 +373,13 @@ func Run(filename string, src interface{}, mode ExecutionMode, allowExternalEntr
|
|||||||
|
|
||||||
var results starlark.StringDict
|
var results starlark.StringDict
|
||||||
mainThread.SetLocal(allowExternalEntrypointKey, allowExternalEntrypoint)
|
mainThread.SetLocal(allowExternalEntrypointKey, allowExternalEntrypoint)
|
||||||
mainThread.SetLocal(callerDirKey, filepath.Dir(filename))
|
mainThread.SetLocal(callingFileKey, filename)
|
||||||
mainThread.SetLocal(executionModeKey, mode)
|
mainThread.SetLocal(executionModeKey, mode)
|
||||||
mainThread.SetLocal(shellKey, shellPath)
|
mainThread.SetLocal(shellKey, shellPath)
|
||||||
if mode == ExecutionModeRbc {
|
if mode == ExecutionModeRbc {
|
||||||
results, err = starlark.ExecFile(mainThread, filename, src, rbcBuiltins)
|
results, err = starlark.ExecFile(mainThread, filename, src, rbcBuiltins)
|
||||||
} else if mode == ExecutionModeMake {
|
} else if mode == ExecutionModeScl {
|
||||||
results, err = starlark.ExecFile(mainThread, filename, src, makeBuiltins)
|
results, err = starlark.ExecFile(mainThread, filename, src, sclBuiltins)
|
||||||
} else {
|
} else {
|
||||||
return results, nil, fmt.Errorf("unknown executionMode %d", mode)
|
return results, nil, fmt.Errorf("unknown executionMode %d", mode)
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"go.starlark.net/resolve"
|
"go.starlark.net/resolve"
|
||||||
@@ -126,7 +127,7 @@ func TestLoad(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
thread.SetLocal(allowExternalEntrypointKey, false)
|
thread.SetLocal(allowExternalEntrypointKey, false)
|
||||||
thread.SetLocal(callerDirKey, dir)
|
thread.SetLocal(callingFileKey, "testdata/load.star")
|
||||||
thread.SetLocal(executionModeKey, ExecutionModeRbc)
|
thread.SetLocal(executionModeKey, ExecutionModeRbc)
|
||||||
if _, err := starlark.ExecFile(thread, "testdata/load.star", nil, rbcBuiltins); err != nil {
|
if _, err := starlark.ExecFile(thread, "testdata/load.star", nil, rbcBuiltins); err != nil {
|
||||||
if err, ok := err.(*starlark.EvalError); ok {
|
if err, ok := err.(*starlark.EvalError); ok {
|
||||||
@@ -136,6 +137,55 @@ func TestLoad(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBzlLoadsScl(t *testing.T) {
|
||||||
|
moduleCache = make(map[string]*modentry)
|
||||||
|
dir := dataDir()
|
||||||
|
if err := os.Chdir(filepath.Dir(dir)); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
vars, _, err := Run("testdata/bzl_loads_scl.bzl", nil, ExecutionModeScl, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if val, ok := vars["foo"]; !ok {
|
||||||
|
t.Fatalf("Failed to load foo variable")
|
||||||
|
} else if val.(starlark.String) != "bar" {
|
||||||
|
t.Fatalf("Expected \"bar\", got %q", val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNonEntrypointBzlLoadsScl(t *testing.T) {
|
||||||
|
moduleCache = make(map[string]*modentry)
|
||||||
|
dir := dataDir()
|
||||||
|
if err := os.Chdir(filepath.Dir(dir)); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
vars, _, err := Run("testdata/bzl_loads_scl_2.bzl", nil, ExecutionModeScl, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if val, ok := vars["foo"]; !ok {
|
||||||
|
t.Fatalf("Failed to load foo variable")
|
||||||
|
} else if val.(starlark.String) != "bar" {
|
||||||
|
t.Fatalf("Expected \"bar\", got %q", val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSclLoadsBzl(t *testing.T) {
|
||||||
|
moduleCache = make(map[string]*modentry)
|
||||||
|
dir := dataDir()
|
||||||
|
if err := os.Chdir(filepath.Dir(dir)); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, _, err := Run("testdata/scl_incorrectly_loads_bzl.scl", nil, ExecutionModeScl, false)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("Expected failure")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), ".scl files can only load other .scl files") {
|
||||||
|
t.Fatalf("Expected error to contain \".scl files can only load other .scl files\": %q", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestShell(t *testing.T) {
|
func TestShell(t *testing.T) {
|
||||||
exerciseStarlarkTestFile(t, "testdata/shell.star")
|
exerciseStarlarkTestFile(t, "testdata/shell.star")
|
||||||
}
|
}
|
||||||
|
@@ -55,13 +55,13 @@ func getMode() rbcrun.ExecutionMode {
|
|||||||
case "rbc":
|
case "rbc":
|
||||||
return rbcrun.ExecutionModeRbc
|
return rbcrun.ExecutionModeRbc
|
||||||
case "make":
|
case "make":
|
||||||
return rbcrun.ExecutionModeMake
|
return rbcrun.ExecutionModeScl
|
||||||
case "":
|
case "":
|
||||||
quit("-mode flag is required.")
|
quit("-mode flag is required.")
|
||||||
default:
|
default:
|
||||||
quit("Unknown -mode value %q, expected 1 of \"rbc\", \"make\"", *modeFlag)
|
quit("Unknown -mode value %q, expected 1 of \"rbc\", \"make\"", *modeFlag)
|
||||||
}
|
}
|
||||||
return rbcrun.ExecutionModeMake
|
return rbcrun.ExecutionModeScl
|
||||||
}
|
}
|
||||||
|
|
||||||
var makeStringReplacer = strings.NewReplacer("#", "\\#", "$", "$$")
|
var makeStringReplacer = strings.NewReplacer("#", "\\#", "$", "$$")
|
||||||
@@ -175,7 +175,7 @@ func main() {
|
|||||||
quit("%s\n", err)
|
quit("%s\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if mode == rbcrun.ExecutionModeMake {
|
if mode == rbcrun.ExecutionModeScl {
|
||||||
if err := printVarsInMakeFormat(variables); err != nil {
|
if err := printVarsInMakeFormat(variables); err != nil {
|
||||||
quit("%s\n", err)
|
quit("%s\n", err)
|
||||||
}
|
}
|
||||||
|
3
tools/rbcrun/testdata/bzl_loads_scl.bzl
vendored
Normal file
3
tools/rbcrun/testdata/bzl_loads_scl.bzl
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
load(":test_scl.scl", _foo = "foo")
|
||||||
|
|
||||||
|
foo = _foo
|
3
tools/rbcrun/testdata/bzl_loads_scl_2.bzl
vendored
Normal file
3
tools/rbcrun/testdata/bzl_loads_scl_2.bzl
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
load(":bzl_loads_scl.bzl", _foo = "foo")
|
||||||
|
|
||||||
|
foo = _foo
|
3
tools/rbcrun/testdata/scl_incorrectly_loads_bzl.scl
vendored
Normal file
3
tools/rbcrun/testdata/scl_incorrectly_loads_bzl.scl
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
load(":bzl_loads_scl.bzl", _foo = "foo")
|
||||||
|
|
||||||
|
foo = _foo
|
2
tools/rbcrun/testdata/test_scl.scl
vendored
Normal file
2
tools/rbcrun/testdata/test_scl.scl
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
foo = "bar"
|
Reference in New Issue
Block a user