This repository has been archived by the owner on Dec 6, 2022. It is now read-only.
forked from mtabini/go-lua
-
Notifications
You must be signed in to change notification settings - Fork 0
/
undump_test.go
105 lines (95 loc) · 2.55 KB
/
undump_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package lua
import (
"bytes"
"encoding/binary"
"io"
"os"
"os/exec"
"path/filepath"
"testing"
)
func TestAllHeaderNoFun(t *testing.T) {
expectErrorFromUndump(io.EOF, header, t)
}
func TestWrongEndian(t *testing.T) {
h := header
if 0 == h.Endianness {
h.Endianness = 1
} else {
h.Endianness = 0
}
expectErrorFromUndump(errIncompatible, h, t)
}
func TestWrongVersion(t *testing.T) {
h := header
h.Version += 1
expectErrorFromUndump(errVersionMismatch, h, t)
}
func TestWrongNumberSize(t *testing.T) {
h := header
h.NumberSize /= 2
expectErrorFromUndump(errIncompatible, h, t)
}
func TestCorruptTail(t *testing.T) {
h := header
h.Tail[3] += 1
expectErrorFromUndump(errCorrupted, h, t)
}
func TestUndump(t *testing.T) {
_, err := exec.LookPath("luac")
if err != nil {
t.Skipf("testing undump requires luac: %s", err)
}
source := filepath.Join("lua-tests", "checktable.lua")
binary := filepath.Join("lua-tests", "checktable.bin")
if err := exec.Command("luac", "-o", binary, source).Run(); err != nil {
t.Fatalf("luac failed to compile %s: %s", source, err)
}
file, err := os.Open(binary)
if err != nil {
t.Fatal("couldn't open checktable.bin")
}
l := NewState()
closure, err := l.undump(file, "test")
if err != nil {
offset, _ := file.Seek(0, 1)
t.Error("unexpected error", err, "at file offset", offset)
}
if closure == nil {
t.Error("closure was nil")
}
p := closure.prototype
if p == nil {
t.Fatal("prototype was nil")
}
validate("@lua-tests/checktable.lua", p.source, "as source file name", t)
validate(23, len(p.code), "instructions", t)
validate(8, len(p.constants), "constants", t)
validate(4, len(p.prototypes), "prototypes", t)
validate(1, len(p.upValues), "upvalues", t)
validate(0, len(p.localVariables), "local variables", t)
validate(0, p.parameterCount, "parameters", t)
validate(4, p.maxStackSize, "stack slots", t)
if !p.isVarArg {
t.Error("expected main function to be var arg, but wasn't")
}
}
func validate(expected, actual interface{}, description string, t *testing.T) {
if expected != actual {
t.Errorf("expected %v %s in main function but found %v", expected, description, actual)
}
}
func expectErrorFromUndump(expected error, data interface{}, t *testing.T) {
l := NewState()
_, err := l.undump(readerOn(data, t), "test")
if err != expected {
t.Error("expected", expected, "but got", err)
}
}
func readerOn(data interface{}, t *testing.T) io.Reader {
buf := new(bytes.Buffer)
if err := binary.Write(buf, endianness(), data); err != nil {
t.Fatal("couldn't serialize data -", err)
}
return buf
}