ulua.L.SetField(pkg, "GetLeadingWhitespace", luar.New(ulua.L, util.LuaGetLeadingWhitespace))
ulua.L.SetField(pkg, "IsWordChar", luar.New(ulua.L, util.LuaIsWordChar))
ulua.L.SetField(pkg, "String", luar.New(ulua.L, util.String))
+ ulua.L.SetField(pkg, "Unzip", luar.New(ulua.L, util.Unzip))
+ ulua.L.SetField(pkg, "Version", luar.New(ulua.L, util.Version))
+ ulua.L.SetField(pkg, "SemVersion", luar.New(ulua.L, util.SemVersion))
ulua.L.SetField(pkg, "CharacterCountInString", luar.New(ulua.L, util.CharacterCountInString))
ulua.L.SetField(pkg, "RuneStr", luar.New(ulua.L, func(r rune) string {
return string(r)
package lua
import (
+ "archive/zip"
"bytes"
"errors"
"fmt"
"math"
"math/rand"
"net"
+ "net/http"
"os"
"path"
"path/filepath"
return importUtf8()
case "humanize":
return importHumanize()
+ case "net/http", "http":
+ return importHTTP()
+ case "archive/zip":
+ return importArchiveZip()
default:
return nil
}
L.SetField(pkg, "Symlink", luar.New(L, os.Symlink))
L.SetField(pkg, "TempDir", luar.New(L, os.TempDir))
L.SetField(pkg, "Truncate", luar.New(L, os.Truncate))
+ L.SetField(pkg, "UserHomeDir", luar.New(L, os.UserHomeDir))
return pkg
}
return pkg
}
+
+func importHTTP() *lua.LTable {
+ pkg := L.NewTable()
+
+ L.SetField(pkg, "Get", luar.New(L, http.Get))
+ L.SetField(pkg, "Post", luar.New(L, http.Post))
+
+ return pkg
+}
+
+func importArchiveZip() *lua.LTable {
+ pkg := L.NewTable()
+
+ L.SetField(pkg, "OpenReader", luar.New(L, zip.OpenReader))
+ L.SetField(pkg, "NewReader", luar.New(L, zip.NewReader))
+ L.SetField(pkg, "NewWriter", luar.New(L, zip.NewWriter))
+
+ return pkg
+}
package util
import (
+ "archive/zip"
"bytes"
"errors"
"fmt"
+ "io"
"os"
"os/user"
"path/filepath"
func String(s []byte) string {
return string(s)
}
+
+// Unzip unzips a file to given folder
+func Unzip(src, dest string) error {
+ r, err := zip.OpenReader(src)
+ if err != nil {
+ return err
+ }
+ defer r.Close()
+
+ os.MkdirAll(dest, 0755)
+
+ // Closure to address file descriptors issue with all the deferred .Close() methods
+ extractAndWriteFile := func(f *zip.File) error {
+ rc, err := f.Open()
+ if err != nil {
+ return err
+ }
+ defer rc.Close()
+
+ path := filepath.Join(dest, f.Name)
+
+ // Check for ZipSlip (Directory traversal)
+ if !strings.HasPrefix(path, filepath.Clean(dest)+string(os.PathSeparator)) {
+ return fmt.Errorf("illegal file path: %s", path)
+ }
+
+ if f.FileInfo().IsDir() {
+ os.MkdirAll(path, f.Mode())
+ } else {
+ os.MkdirAll(filepath.Dir(path), f.Mode())
+ f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ _, err = io.Copy(f, rc)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+ }
+
+ for _, f := range r.File {
+ err := extractAndWriteFile(f)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
string is a word character.
- `String(b []byte) string`: converts a byte array to a string.
- `RuneStr(r rune) string`: converts a rune to a string.
+ - `Unzip(src, dest string) error`: unzips a file to given folder.
This may seem like a small list of available functions but some of the objects
returned by the functions have many methods. The Lua plugin may access any
regexp
errors
time
+archive/zip
+net/http
```
For documentation for each of these functions, see the Go standard