Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f85e863d authored by Cole Faust's avatar Cole Faust Committed by Automerger Merge Worker
Browse files

Merge "Only allow .scl files to load other .scl files" into main am: 7c860771

parents 865c4ef4 7c860771
Loading
Loading
Loading
Loading
+19 −11
Original line number Diff line number Diff line
@@ -31,11 +31,11 @@ import (
type ExecutionMode int
const (
	ExecutionModeRbc ExecutionMode = iota
	ExecutionModeMake ExecutionMode = iota
	ExecutionModeScl ExecutionMode = iota
)

const allowExternalEntrypointKey = "allowExternalEntrypoint"
const callerDirKey = "callerDir"
const callingFileKey = "callingFile"
const executionModeKey = "executionMode"
const shellKey = "shell"

@@ -58,7 +58,7 @@ var rbcBuiltins starlark.StringDict = starlark.StringDict{
	"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),
	"json": starlarkjson.Module,
}
@@ -128,7 +128,8 @@ func loader(thread *starlark.Thread, module string) (starlark.StringDict, error)
			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 {
		return nil, err
	}
@@ -150,6 +151,13 @@ func loader(thread *starlark.Thread, module string) (starlark.StringDict, error)

		// Load or return default
		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}
			// Cheating for the sake of 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.
			childThread.SetLocal(allowExternalEntrypointKey, false)
			childThread.SetLocal(callerDirKey, filepath.Dir(modulePath))
			childThread.SetLocal(callingFileKey, modulePath)
			childThread.SetLocal(executionModeKey, mode)
			childThread.SetLocal(shellKey, thread.Local(shellKey))
			if mode == ExecutionModeRbc {
				globals, err := starlark.ExecFile(childThread, modulePath, nil, rbcBuiltins)
				e = &modentry{globals, err}
			} else if mode == ExecutionModeMake {
				globals, err := starlark.ExecFile(childThread, modulePath, nil, makeBuiltins)
			} else if mode == ExecutionModeScl {
				globals, err := starlark.ExecFile(childThread, modulePath, nil, sclBuiltins)
				e = &modentry{globals, err}
			} else {
				return nil, fmt.Errorf("unknown executionMode %d", mode)
@@ -338,7 +346,7 @@ func Run(filename string, src interface{}, mode ExecutionMode, allowExternalEntr
			if mode == ExecutionModeRbc {
				// In rbc mode, rblf_log is used to print to stderr
				fmt.Println(msg)
			} else if mode == ExecutionModeMake {
			} else if mode == ExecutionModeScl {
				fmt.Fprintln(os.Stderr, msg)
			}
		},
@@ -365,13 +373,13 @@ func Run(filename string, src interface{}, mode ExecutionMode, allowExternalEntr

	var results starlark.StringDict
	mainThread.SetLocal(allowExternalEntrypointKey, allowExternalEntrypoint)
	mainThread.SetLocal(callerDirKey, filepath.Dir(filename))
	mainThread.SetLocal(callingFileKey, filename)
	mainThread.SetLocal(executionModeKey, mode)
	mainThread.SetLocal(shellKey, shellPath)
	if mode == ExecutionModeRbc {
		results, err = starlark.ExecFile(mainThread, filename, src, rbcBuiltins)
	} else if mode == ExecutionModeMake {
		results, err = starlark.ExecFile(mainThread, filename, src, makeBuiltins)
	} else if mode == ExecutionModeScl {
		results, err = starlark.ExecFile(mainThread, filename, src, sclBuiltins)
	} else {
		return results, nil, fmt.Errorf("unknown executionMode %d", mode)
	}
+51 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import (
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"testing"

	"go.starlark.net/resolve"
@@ -126,7 +127,7 @@ func TestLoad(t *testing.T) {
		t.Fatal(err)
	}
	thread.SetLocal(allowExternalEntrypointKey, false)
	thread.SetLocal(callerDirKey, dir)
	thread.SetLocal(callingFileKey, "testdata/load.star")
	thread.SetLocal(executionModeKey, ExecutionModeRbc)
	if _, err := starlark.ExecFile(thread, "testdata/load.star", nil, rbcBuiltins); err != nil {
		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) {
	exerciseStarlarkTestFile(t, "testdata/shell.star")
}
+3 −3
Original line number Diff line number Diff line
@@ -55,13 +55,13 @@ func getMode() rbcrun.ExecutionMode {
	case "rbc":
		return rbcrun.ExecutionModeRbc
	case "make":
		return rbcrun.ExecutionModeMake
		return rbcrun.ExecutionModeScl
	case "":
		quit("-mode flag is required.")
	default:
		quit("Unknown -mode value %q, expected 1 of \"rbc\", \"make\"", *modeFlag)
	}
	return rbcrun.ExecutionModeMake
	return rbcrun.ExecutionModeScl
}

var makeStringReplacer = strings.NewReplacer("#", "\\#", "$", "$$")
@@ -175,7 +175,7 @@ func main() {
			quit("%s\n", err)
		}
	}
	if mode == rbcrun.ExecutionModeMake {
	if mode == rbcrun.ExecutionModeScl {
		if err := printVarsInMakeFormat(variables); err != nil {
			quit("%s\n", err)
		}
+3 −0
Original line number Diff line number Diff line
load(":test_scl.scl", _foo = "foo")

foo = _foo
+3 −0
Original line number Diff line number Diff line
load(":bzl_loads_scl.bzl", _foo = "foo")

foo = _foo
Loading