123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- package frankenphp
- // #cgo nocallback frankenphp_init_persistent_string
- // #cgo nocallback frankenphp_add_assoc_str_ex
- // #cgo noescape frankenphp_init_persistent_string
- // #cgo noescape frankenphp_add_assoc_str_ex
- // #include "frankenphp.h"
- import "C"
- import (
- "os"
- "strings"
- "unsafe"
- )
- func initializeEnv() map[string]*C.zend_string {
- env := os.Environ()
- envMap := make(map[string]*C.zend_string, len(env))
- for _, envVar := range env {
- key, val, _ := strings.Cut(envVar, "=")
- envMap[key] = C.frankenphp_init_persistent_string(toUnsafeChar(val), C.size_t(len(val)))
- }
- return envMap
- }
- // get the main thread env or the thread specific env
- func getSandboxedEnv(thread *phpThread) map[string]*C.zend_string {
- if thread.sandboxedEnv != nil {
- return thread.sandboxedEnv
- }
- return mainThread.sandboxedEnv
- }
- func clearSandboxedEnv(thread *phpThread) {
- if thread.sandboxedEnv == nil {
- return
- }
- for key, val := range thread.sandboxedEnv {
- valInMainThread, ok := mainThread.sandboxedEnv[key]
- if !ok || val != valInMainThread {
- C.free(unsafe.Pointer(val))
- }
- }
- thread.sandboxedEnv = nil
- }
- // if an env var already exists, it needs to be freed
- func removeEnvFromThread(thread *phpThread, key string) {
- valueInThread, existsInThread := thread.sandboxedEnv[key]
- if !existsInThread {
- return
- }
- valueInMainThread, ok := mainThread.sandboxedEnv[key]
- if !ok || valueInThread != valueInMainThread {
- C.free(unsafe.Pointer(valueInThread))
- }
- delete(thread.sandboxedEnv, key)
- }
- // copy the main thread env to the thread specific env
- func cloneSandboxedEnv(thread *phpThread) {
- if thread.sandboxedEnv != nil {
- return
- }
- thread.sandboxedEnv = make(map[string]*C.zend_string, len(mainThread.sandboxedEnv))
- for key, value := range mainThread.sandboxedEnv {
- thread.sandboxedEnv[key] = value
- }
- }
- //export go_putenv
- func go_putenv(threadIndex C.uintptr_t, str *C.char, length C.int) C.bool {
- thread := phpThreads[threadIndex]
- envString := C.GoStringN(str, length)
- cloneSandboxedEnv(thread)
- // Check if '=' is present in the string
- if key, val, found := strings.Cut(envString, "="); found {
- removeEnvFromThread(thread, key)
- thread.sandboxedEnv[key] = C.frankenphp_init_persistent_string(toUnsafeChar(val), C.size_t(len(val)))
- return os.Setenv(key, val) == nil
- }
- // No '=', unset the environment variable
- removeEnvFromThread(thread, envString)
- return os.Unsetenv(envString) == nil
- }
- //export go_getfullenv
- func go_getfullenv(threadIndex C.uintptr_t, trackVarsArray *C.zval) {
- thread := phpThreads[threadIndex]
- env := getSandboxedEnv(thread)
- for key, val := range env {
- C.frankenphp_add_assoc_str_ex(trackVarsArray, toUnsafeChar(key), C.size_t(len(key)), val)
- }
- }
- //export go_getenv
- func go_getenv(threadIndex C.uintptr_t, name *C.char) (C.bool, *C.zend_string) {
- thread := phpThreads[threadIndex]
- // Get the environment variable value
- envValue, exists := getSandboxedEnv(thread)[C.GoString(name)]
- if !exists {
- // Environment variable does not exist
- return false, nil // Return 0 to indicate failure
- }
- return true, envValue // Return 1 to indicate success
- }
|