aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2024-12-06 00:27:35 +0700
committerShulhan <ms@kilabit.info>2024-12-06 01:32:03 +0700
commitecd9b25e75f2a5fa53af8ea0111549119858bc70 (patch)
tree3656de77def3d09ccf6d5fba1ca874233ad517e0
parent904296da2f93b1376d7e2f5395ad11053ec7ab59 (diff)
downloadpakakeh.go-ecd9b25e75f2a5fa53af8ea0111549119858bc70.tar.xz
lib/play: add custom request to run unsafe directory directly
As exceptional, the Run and HTTPHandleRun accept the following request for running program inside custom "go.mod", { "unsafe_run": <path> } The "unsafe_run" define the path to directory relative to HTTP server working directory. Once request accepted it will change the directory into "unsafe_run" first and then run "go run ." directly. Go code that executed inside "unsafe_run" should be not modifiable and safe from mallicious execution.
-rw-r--r--lib/play/play.go37
-rw-r--r--lib/play/play_test.go18
-rw-r--r--lib/play/request.go4
-rw-r--r--lib/play/testdata/unsafe_run/cmd/forum/main.go7
-rw-r--r--lib/play/testdata/unsafe_run/forum/forum.go7
-rw-r--r--lib/play/testdata/unsafe_run/go.mod3
6 files changed, 74 insertions, 2 deletions
diff --git a/lib/play/play.go b/lib/play/play.go
index 068a52c2..3f01035d 100644
--- a/lib/play/play.go
+++ b/lib/play/play.go
@@ -20,11 +20,11 @@
// used to compile the code.
// The default "goversion" is defined as global variable [GoVersion] in this
// package.
-// If "without_race" is false, the Run command will not run with "-race"
+// If "without_race" is true, the Run command will not run with "-race"
// option.
// The "body" field contains the Go code to be formatted or run.
//
-// Both have the following response format,
+// Both return the following JSON response format,
//
// {
// "code": <integer, HTTP status code>,
@@ -38,6 +38,20 @@
// For the [HTTPHandleRun], the response "data" contains the output from
// running the Go code, the "message" contains an error pre-Run, like bad
// request or file system related error.
+//
+// As exceptional, the [Run] and [HTTPHandleRun] accept the following
+// request for running program inside custom "go.mod",
+//
+// {
+// "unsafe_run": <path>
+// }
+//
+// The "unsafe_run" define the path to directory relative to HTTP server
+// working directory.
+// Once request accepted it will change the directory into "unsafe_run" first
+// and then run "go run ." directly.
+// Go code that executed inside "unsafe_run" should be not modifiable and
+// safe from mallicious execution.
package play
import (
@@ -253,6 +267,10 @@ func Run(req *Request) (out []byte, err error) {
runningCmd.delete(req.cookieSid.Value)
}
+ if len(req.UnsafeRun) != 0 {
+ return unsafeRun(req)
+ }
+
if len(req.Body) == 0 {
return nil, nil
}
@@ -296,3 +314,18 @@ func Run(req *Request) (out []byte, err error) {
return out, nil
}
+
+func unsafeRun(req *Request) (out []byte, err error) {
+ var logp = `unsafeRun`
+
+ var cmd *command
+ cmd, err = newCommand(req, req.UnsafeRun)
+ if err != nil {
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
+ }
+ runningCmd.store(req.cookieSid.Value, cmd)
+
+ out = cmd.run()
+
+ return out, nil
+}
diff --git a/lib/play/play_test.go b/lib/play/play_test.go
index 4172c506..f9acf460 100644
--- a/lib/play/play_test.go
+++ b/lib/play/play_test.go
@@ -320,3 +320,21 @@ func testRunOverlap(t *testing.T, runwg *sync.WaitGroup, tdata *test.Data,
exp, string(out))
}
}
+
+func TestRunUnsafeRun(t *testing.T) {
+ var req = &Request{
+ UnsafeRun: `testdata/unsafe_run/cmd/forum`,
+ }
+
+ var (
+ out []byte
+ err error
+ )
+ out, err = Run(req)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ var exp = "Hello...\n"
+ test.Assert(t, `unsafeRun`, exp, string(out))
+}
diff --git a/lib/play/request.go b/lib/play/request.go
index 18c210bd..3bd8cfb5 100644
--- a/lib/play/request.go
+++ b/lib/play/request.go
@@ -29,6 +29,10 @@ type Request struct {
// Body contains the Go code to be Format-ed or Run.
Body string `json:"body"`
+ // UnsafeRun define the working directory where "go run ." will be
+ // executed directly.
+ UnsafeRun string `json:"unsafe_run"`
+
// WithoutRace define option opt out "-race" when running Go code.
WithoutRace bool `json:"without_race"`
}
diff --git a/lib/play/testdata/unsafe_run/cmd/forum/main.go b/lib/play/testdata/unsafe_run/cmd/forum/main.go
new file mode 100644
index 00000000..c8fb90ef
--- /dev/null
+++ b/lib/play/testdata/unsafe_run/cmd/forum/main.go
@@ -0,0 +1,7 @@
+package main
+
+import "forum.local/forum"
+
+func main() {
+ forum.Write("Hello...")
+}
diff --git a/lib/play/testdata/unsafe_run/forum/forum.go b/lib/play/testdata/unsafe_run/forum/forum.go
new file mode 100644
index 00000000..4401b9da
--- /dev/null
+++ b/lib/play/testdata/unsafe_run/forum/forum.go
@@ -0,0 +1,7 @@
+package forum
+
+import "fmt"
+
+func Write(text string) {
+ fmt.Println(text)
+}
diff --git a/lib/play/testdata/unsafe_run/go.mod b/lib/play/testdata/unsafe_run/go.mod
new file mode 100644
index 00000000..f0a7067f
--- /dev/null
+++ b/lib/play/testdata/unsafe_run/go.mod
@@ -0,0 +1,3 @@
+module forum.local
+
+go 1.23.2