Move Go lua libs to lualibs
This commit is contained in:
parent
61f66d6594
commit
86a122a50c
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"Moonshark/router"
|
"Moonshark/router"
|
||||||
"Moonshark/runner"
|
"Moonshark/runner"
|
||||||
|
"Moonshark/runner/lualibs"
|
||||||
"Moonshark/sessions"
|
"Moonshark/sessions"
|
||||||
"Moonshark/utils"
|
"Moonshark/utils"
|
||||||
"Moonshark/utils/color"
|
"Moonshark/utils/color"
|
||||||
@ -173,8 +174,8 @@ func (s *Server) handleLuaRoute(ctx *fasthttp.RequestCtx, bytecode []byte, scrip
|
|||||||
luaCtx := runner.NewHTTPContext(ctx)
|
luaCtx := runner.NewHTTPContext(ctx)
|
||||||
defer luaCtx.Release()
|
defer luaCtx.Release()
|
||||||
|
|
||||||
if runner.GetGlobalEnvManager() != nil {
|
if lualibs.GetGlobalEnvManager() != nil {
|
||||||
luaCtx.Set("env", runner.GetGlobalEnvManager().GetAll())
|
luaCtx.Set("env", lualibs.GetGlobalEnvManager().GetAll())
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionMap := s.ctxPool.Get().(map[string]any)
|
sessionMap := s.ctxPool.Get().(map[string]any)
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"Moonshark/http"
|
"Moonshark/http"
|
||||||
"Moonshark/router"
|
"Moonshark/router"
|
||||||
"Moonshark/runner"
|
"Moonshark/runner"
|
||||||
|
"Moonshark/runner/lualibs"
|
||||||
"Moonshark/sessions"
|
"Moonshark/sessions"
|
||||||
"Moonshark/utils/color"
|
"Moonshark/utils/color"
|
||||||
"Moonshark/utils/config"
|
"Moonshark/utils/config"
|
||||||
@ -144,7 +145,7 @@ func (s *Moonshark) initRunner(poolSize int) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := runner.InitEnv(s.Config.Dirs.Data); err != nil {
|
if err := lualibs.InitEnv(s.Config.Dirs.Data); err != nil {
|
||||||
logger.Warnf("Environment initialization failed: %v", err)
|
logger.Warnf("Environment initialization failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +288,7 @@ func (s *Moonshark) Shutdown() error {
|
|||||||
s.LuaRunner.Close()
|
s.LuaRunner.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := runner.CleanupEnv(); err != nil {
|
if err := lualibs.CleanupEnv(); err != nil {
|
||||||
logger.Warnf("Environment cleanup failed: %v", err)
|
logger.Warnf("Environment cleanup failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package runner
|
package lualibs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"Moonshark/utils/logger"
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/sha512"
|
"crypto/sha512"
|
||||||
|
"encoding/base64"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -32,6 +34,10 @@ func RegisterCryptoFunctions(state *luajit.State) error {
|
|||||||
stateRngs[state] = mrand.NewPCG(uint64(time.Now().UnixNano()), uint64(time.Now().UnixNano()>>32))
|
stateRngs[state] = mrand.NewPCG(uint64(time.Now().UnixNano()), uint64(time.Now().UnixNano()>>32))
|
||||||
stateRngsMu.Unlock()
|
stateRngsMu.Unlock()
|
||||||
|
|
||||||
|
if err := state.RegisterGoFunction("__generate_token", generateToken); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Register hash functions
|
// Register hash functions
|
||||||
if err := state.RegisterGoFunction("__crypto_hash", cryptoHash); err != nil {
|
if err := state.RegisterGoFunction("__crypto_hash", cryptoHash); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -419,3 +425,39 @@ func OverrideLuaRandom(state *luajit.State) error {
|
|||||||
go_math_randomseed = nil
|
go_math_randomseed = nil
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generateToken creates a cryptographically secure random token
|
||||||
|
func generateToken(state *luajit.State) int {
|
||||||
|
// Get the length from the Lua arguments (default to 32)
|
||||||
|
length := 32
|
||||||
|
if state.GetTop() >= 1 {
|
||||||
|
if lengthVal, err := state.SafeToNumber(1); err == nil {
|
||||||
|
length = int(lengthVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enforce minimum length for security
|
||||||
|
if length < 16 {
|
||||||
|
length = 16
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate secure random bytes
|
||||||
|
tokenBytes := make([]byte, length)
|
||||||
|
if _, err := rand.Read(tokenBytes); err != nil {
|
||||||
|
logger.Errorf("Failed to generate secure token: %v", err)
|
||||||
|
state.PushString("")
|
||||||
|
return 1 // Return empty string on error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode as base64
|
||||||
|
token := base64.RawURLEncoding.EncodeToString(tokenBytes)
|
||||||
|
|
||||||
|
// Trim to requested length (base64 might be longer)
|
||||||
|
if len(token) > length {
|
||||||
|
token = token[:length]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push the token to the Lua stack
|
||||||
|
state.PushString(token)
|
||||||
|
return 1 // One return value
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package runner
|
package lualibs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
@ -1,4 +1,4 @@
|
|||||||
package runner
|
package lualibs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
@ -1,9 +1,7 @@
|
|||||||
package runner
|
package lualibs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
|
||||||
"encoding/base64"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -14,8 +12,6 @@ import (
|
|||||||
"github.com/valyala/bytebufferpool"
|
"github.com/valyala/bytebufferpool"
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
|
|
||||||
"Moonshark/utils/logger"
|
|
||||||
|
|
||||||
luajit "git.sharkk.net/Sky/LuaJIT-to-Go"
|
luajit "git.sharkk.net/Sky/LuaJIT-to-Go"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -44,52 +40,13 @@ var DefaultHTTPClientConfig = HTTPClientConfig{
|
|||||||
AllowRemote: true,
|
AllowRemote: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ApplyResponse applies a Response to a fasthttp.RequestCtx
|
// RegisterHttpFunctions registers HTTP functions with the Lua state
|
||||||
func ApplyResponse(resp *Response, ctx *fasthttp.RequestCtx) {
|
func RegisterHttpFunctions(state *luajit.State) error {
|
||||||
// Set status code
|
if err := state.RegisterGoFunction("__http_request", httpRequest); err != nil {
|
||||||
ctx.SetStatusCode(resp.Status)
|
return err
|
||||||
|
|
||||||
// Set headers
|
|
||||||
for name, value := range resp.Headers {
|
|
||||||
ctx.Response.Header.Set(name, value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set cookies
|
return nil
|
||||||
for _, cookie := range resp.Cookies {
|
|
||||||
ctx.Response.Header.SetCookie(cookie)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process the body based on its type
|
|
||||||
if resp.Body == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get a buffer from the pool
|
|
||||||
buf := bytebufferpool.Get()
|
|
||||||
defer bytebufferpool.Put(buf)
|
|
||||||
|
|
||||||
// Set body based on type
|
|
||||||
switch body := resp.Body.(type) {
|
|
||||||
case string:
|
|
||||||
ctx.SetBodyString(body)
|
|
||||||
case []byte:
|
|
||||||
ctx.SetBody(body)
|
|
||||||
case map[string]any, []any, []float64, []string, []int:
|
|
||||||
// Marshal JSON
|
|
||||||
if err := json.NewEncoder(buf).Encode(body); err == nil {
|
|
||||||
// Set content type if not already set
|
|
||||||
if len(ctx.Response.Header.ContentType()) == 0 {
|
|
||||||
ctx.Response.Header.SetContentType("application/json")
|
|
||||||
}
|
|
||||||
ctx.SetBody(buf.Bytes())
|
|
||||||
} else {
|
|
||||||
// Fallback
|
|
||||||
ctx.SetBodyString(fmt.Sprintf("%v", body))
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
// Default to string representation
|
|
||||||
ctx.SetBodyString(fmt.Sprintf("%v", body))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// httpRequest makes an HTTP request and returns the result to Lua
|
// httpRequest makes an HTTP request and returns the result to Lua
|
||||||
@ -277,39 +234,3 @@ func httpRequest(state *luajit.State) int {
|
|||||||
builder.Build()
|
builder.Build()
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateToken creates a cryptographically secure random token
|
|
||||||
func generateToken(state *luajit.State) int {
|
|
||||||
// Get the length from the Lua arguments (default to 32)
|
|
||||||
length := 32
|
|
||||||
if state.GetTop() >= 1 {
|
|
||||||
if lengthVal, err := state.SafeToNumber(1); err == nil {
|
|
||||||
length = int(lengthVal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enforce minimum length for security
|
|
||||||
if length < 16 {
|
|
||||||
length = 16
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate secure random bytes
|
|
||||||
tokenBytes := make([]byte, length)
|
|
||||||
if _, err := rand.Read(tokenBytes); err != nil {
|
|
||||||
logger.Errorf("Failed to generate secure token: %v", err)
|
|
||||||
state.PushString("")
|
|
||||||
return 1 // Return empty string on error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode as base64
|
|
||||||
token := base64.RawURLEncoding.EncodeToString(tokenBytes)
|
|
||||||
|
|
||||||
// Trim to requested length (base64 might be longer)
|
|
||||||
if len(token) > length {
|
|
||||||
token = token[:length]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push the token to the Lua stack
|
|
||||||
state.PushString(token)
|
|
||||||
return 1 // One return value
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package runner
|
package lualibs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
luajit "git.sharkk.net/Sky/LuaJIT-to-Go"
|
luajit "git.sharkk.net/Sky/LuaJIT-to-Go"
|
@ -1,4 +1,4 @@
|
|||||||
package runner
|
package lualibs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
@ -1,7 +1,8 @@
|
|||||||
package runner
|
package lualibs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
"html"
|
"html"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -10,6 +11,14 @@ import (
|
|||||||
|
|
||||||
// RegisterUtilFunctions registers utility functions with the Lua state
|
// RegisterUtilFunctions registers utility functions with the Lua state
|
||||||
func RegisterUtilFunctions(state *luajit.State) error {
|
func RegisterUtilFunctions(state *luajit.State) error {
|
||||||
|
if err := state.RegisterGoFunction("__json_marshal", jsonMarshal); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := state.RegisterGoFunction("__json_unmarshal", jsonUnmarshal); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// HTML special chars
|
// HTML special chars
|
||||||
if err := state.RegisterGoFunction("__html_special_chars", htmlSpecialChars); err != nil {
|
if err := state.RegisterGoFunction("__html_special_chars", htmlSpecialChars); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -134,3 +143,49 @@ func base64Decode(state *luajit.State) int {
|
|||||||
state.PushString(string(result))
|
state.PushString(string(result))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// jsonMarshal converts a Lua value to a JSON string with validation
|
||||||
|
func jsonMarshal(state *luajit.State) int {
|
||||||
|
if err := state.CheckExactArgs(1); err != nil {
|
||||||
|
return state.PushError("json marshal: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err := state.SafeToTable(1)
|
||||||
|
if err != nil {
|
||||||
|
// Try as generic value if not a table
|
||||||
|
value, err = state.ToValue(1)
|
||||||
|
if err != nil {
|
||||||
|
return state.PushError("json marshal error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes, err := json.Marshal(value)
|
||||||
|
if err != nil {
|
||||||
|
return state.PushError("json marshal error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
state.PushString(string(bytes))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// jsonUnmarshal converts a JSON string to a Lua value with validation
|
||||||
|
func jsonUnmarshal(state *luajit.State) int {
|
||||||
|
if err := state.CheckExactArgs(1); err != nil {
|
||||||
|
return state.PushError("json unmarshal: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonStr, err := state.SafeToString(1)
|
||||||
|
if err != nil {
|
||||||
|
return state.PushError("json unmarshal: expected string, got %s", state.GetType(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
var value any
|
||||||
|
if err := json.Unmarshal([]byte(jsonStr), &value); err != nil {
|
||||||
|
return state.PushError("json unmarshal error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := state.PushValue(value); err != nil {
|
||||||
|
return state.PushError("json unmarshal error: %v", err)
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package runner
|
package runner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"Moonshark/runner/lualibs"
|
||||||
"Moonshark/utils/color"
|
"Moonshark/utils/color"
|
||||||
"Moonshark/utils/logger"
|
"Moonshark/utils/logger"
|
||||||
"context"
|
"context"
|
||||||
@ -15,6 +16,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
luajit "git.sharkk.net/Sky/LuaJIT-to-Go"
|
luajit "git.sharkk.net/Sky/LuaJIT-to-Go"
|
||||||
|
"github.com/goccy/go-json"
|
||||||
|
"github.com/valyala/bytebufferpool"
|
||||||
|
"github.com/valyala/fasthttp"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Common errors
|
// Common errors
|
||||||
@ -112,10 +116,10 @@ func NewRunner(options ...RunnerOption) (*Runner, error) {
|
|||||||
runner.moduleLoader = NewModuleLoader(config)
|
runner.moduleLoader = NewModuleLoader(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
InitSQLite(runner.dataDir)
|
lualibs.InitSQLite(runner.dataDir)
|
||||||
InitFS(runner.fsDir)
|
lualibs.InitFS(runner.fsDir)
|
||||||
|
|
||||||
SetSQLitePoolSize(runner.poolSize)
|
lualibs.SetSQLitePoolSize(runner.poolSize)
|
||||||
|
|
||||||
// Initialize states and pool
|
// Initialize states and pool
|
||||||
runner.states = make([]*State, runner.poolSize)
|
runner.states = make([]*State, runner.poolSize)
|
||||||
@ -123,7 +127,7 @@ func NewRunner(options ...RunnerOption) (*Runner, error) {
|
|||||||
|
|
||||||
// Create and initialize all states
|
// Create and initialize all states
|
||||||
if err := runner.initializeStates(); err != nil {
|
if err := runner.initializeStates(); err != nil {
|
||||||
CleanupSQLite()
|
lualibs.CleanupSQLite()
|
||||||
runner.Close()
|
runner.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -310,8 +314,8 @@ waitForInUse:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CleanupFS()
|
lualibs.CleanupFS()
|
||||||
CleanupSQLite()
|
lualibs.CleanupSQLite()
|
||||||
|
|
||||||
logger.Debugf("Runner closed")
|
logger.Debugf("Runner closed")
|
||||||
return nil
|
return nil
|
||||||
@ -564,3 +568,51 @@ func (r *Runner) RunScriptFile(filePath string) (*Response, error) {
|
|||||||
|
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ApplyResponse applies a Response to a fasthttp.RequestCtx
|
||||||
|
func ApplyResponse(resp *Response, ctx *fasthttp.RequestCtx) {
|
||||||
|
// Set status code
|
||||||
|
ctx.SetStatusCode(resp.Status)
|
||||||
|
|
||||||
|
// Set headers
|
||||||
|
for name, value := range resp.Headers {
|
||||||
|
ctx.Response.Header.Set(name, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set cookies
|
||||||
|
for _, cookie := range resp.Cookies {
|
||||||
|
ctx.Response.Header.SetCookie(cookie)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the body based on its type
|
||||||
|
if resp.Body == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a buffer from the pool
|
||||||
|
buf := bytebufferpool.Get()
|
||||||
|
defer bytebufferpool.Put(buf)
|
||||||
|
|
||||||
|
// Set body based on type
|
||||||
|
switch body := resp.Body.(type) {
|
||||||
|
case string:
|
||||||
|
ctx.SetBodyString(body)
|
||||||
|
case []byte:
|
||||||
|
ctx.SetBody(body)
|
||||||
|
case map[string]any, []any, []float64, []string, []int:
|
||||||
|
// Marshal JSON
|
||||||
|
if err := json.NewEncoder(buf).Encode(body); err == nil {
|
||||||
|
// Set content type if not already set
|
||||||
|
if len(ctx.Response.Header.ContentType()) == 0 {
|
||||||
|
ctx.Response.Header.SetContentType("application/json")
|
||||||
|
}
|
||||||
|
ctx.SetBody(buf.Bytes())
|
||||||
|
} else {
|
||||||
|
// Fallback
|
||||||
|
ctx.SetBodyString(fmt.Sprintf("%v", body))
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// Default to string representation
|
||||||
|
ctx.SetBodyString(fmt.Sprintf("%v", body))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,9 +4,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/goccy/go-json"
|
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
|
|
||||||
|
"Moonshark/runner/lualibs"
|
||||||
"Moonshark/utils/logger"
|
"Moonshark/utils/logger"
|
||||||
|
|
||||||
"maps"
|
"maps"
|
||||||
@ -85,43 +85,31 @@ func (s *Sandbox) Setup(state *luajit.State, verbose bool) error {
|
|||||||
|
|
||||||
// registerCoreFunctions registers all built-in functions in the Lua state
|
// registerCoreFunctions registers all built-in functions in the Lua state
|
||||||
func (s *Sandbox) registerCoreFunctions(state *luajit.State) error {
|
func (s *Sandbox) registerCoreFunctions(state *luajit.State) error {
|
||||||
if err := state.RegisterGoFunction("__http_request", httpRequest); err != nil {
|
if err := lualibs.RegisterHttpFunctions(state); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := state.RegisterGoFunction("__generate_token", generateToken); err != nil {
|
if err := lualibs.RegisterSQLiteFunctions(state); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := state.RegisterGoFunction("__json_marshal", jsonMarshal); err != nil {
|
if err := lualibs.RegisterFSFunctions(state); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := state.RegisterGoFunction("__json_unmarshal", jsonUnmarshal); err != nil {
|
if err := lualibs.RegisterPasswordFunctions(state); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := RegisterSQLiteFunctions(state); err != nil {
|
if err := lualibs.RegisterUtilFunctions(state); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := RegisterFSFunctions(state); err != nil {
|
if err := lualibs.RegisterCryptoFunctions(state); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := RegisterPasswordFunctions(state); err != nil {
|
if err := lualibs.RegisterEnvFunctions(state); err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := RegisterUtilFunctions(state); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := RegisterCryptoFunctions(state); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := RegisterEnvFunctions(state); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,49 +238,3 @@ func extractCookie(state *luajit.State, response *Response) {
|
|||||||
|
|
||||||
response.Cookies = append(response.Cookies, cookie)
|
response.Cookies = append(response.Cookies, cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
// jsonMarshal converts a Lua value to a JSON string with validation
|
|
||||||
func jsonMarshal(state *luajit.State) int {
|
|
||||||
if err := state.CheckExactArgs(1); err != nil {
|
|
||||||
return state.PushError("json marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
value, err := state.SafeToTable(1)
|
|
||||||
if err != nil {
|
|
||||||
// Try as generic value if not a table
|
|
||||||
value, err = state.ToValue(1)
|
|
||||||
if err != nil {
|
|
||||||
return state.PushError("json marshal error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes, err := json.Marshal(value)
|
|
||||||
if err != nil {
|
|
||||||
return state.PushError("json marshal error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
state.PushString(string(bytes))
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// jsonUnmarshal converts a JSON string to a Lua value with validation
|
|
||||||
func jsonUnmarshal(state *luajit.State) int {
|
|
||||||
if err := state.CheckExactArgs(1); err != nil {
|
|
||||||
return state.PushError("json unmarshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonStr, err := state.SafeToString(1)
|
|
||||||
if err != nil {
|
|
||||||
return state.PushError("json unmarshal: expected string, got %s", state.GetType(1))
|
|
||||||
}
|
|
||||||
|
|
||||||
var value any
|
|
||||||
if err := json.Unmarshal([]byte(jsonStr), &value); err != nil {
|
|
||||||
return state.PushError("json unmarshal error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := state.PushValue(value); err != nil {
|
|
||||||
return state.PushError("json unmarshal error: %v", err)
|
|
||||||
}
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user