-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprometheus_test.go
More file actions
241 lines (229 loc) · 6.17 KB
/
Copy pathprometheus_test.go
File metadata and controls
241 lines (229 loc) · 6.17 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
package prometheus
import (
"fmt"
"strings"
"sync"
"testing"
)
const helloLua = `print("Hello, World!")`
func TestObfuscate_DefaultConfig(t *testing.T) {
o := New(Config{})
out, err := o.Obfuscate(helloLua)
if err != nil {
t.Fatalf("Obfuscate: %v", err)
}
if out == "" {
t.Fatal("empty output")
}
}
func TestObfuscate_TransformsCode(t *testing.T) {
o := New(Config{Preset: PresetMedium, Seed: 12345})
out, err := o.Obfuscate(helloLua)
if err != nil {
t.Fatalf("Obfuscate: %v", err)
}
if strings.Contains(out, `print("Hello, World!")`) {
t.Errorf("output still contains original source:\n%s", out)
}
}
func TestObfuscate_AllPresets(t *testing.T) {
for _, p := range []Preset{PresetMinify, PresetWeak, PresetMedium, PresetStrong, PresetOTClient} {
p := p
t.Run(string(p), func(t *testing.T) {
o := New(Config{Preset: p, Seed: 1})
out, err := o.Obfuscate(helloLua)
if err != nil {
t.Fatalf("preset %s: %v", p, err)
}
if out == "" {
t.Fatalf("preset %s: empty output", p)
}
})
}
}
func TestObfuscate_DeterministicSeed(t *testing.T) {
o := New(Config{Preset: PresetMedium, Seed: 4242})
a, err := o.Obfuscate(helloLua)
if err != nil {
t.Fatal(err)
}
b, err := o.Obfuscate(helloLua)
if err != nil {
t.Fatal(err)
}
if a != b {
t.Errorf("seed did not produce deterministic output\nA:\n%s\nB:\n%s", a, b)
}
}
func TestObfuscate_UnknownPreset(t *testing.T) {
o := New(Config{Preset: "Bogus"})
if _, err := o.Obfuscate(helloLua); err == nil {
t.Fatal("expected error for unknown preset")
}
}
// TestObfuscate_LargeLocaleTable exercises the unparser's joinParts ->
// table.concat path on a TableExpression with thousands of fields (i18n
// locale style). With the default gopher-lua state (RegistryMaxSize=0)
// this path runs out of registry slots and crashes. The fix in
// ObfuscateNamed enables registry auto-grow.
//
// Skipped under -short because gopher-lua takes several seconds even for
// this reduced size. Increase the entry count to stress larger workloads.
func TestObfuscate_LargeLocaleTable(t *testing.T) {
if testing.Short() {
t.Skip("skipping large-table test in short mode")
}
const entries = 1500
var b strings.Builder
b.Grow(entries * 96)
b.WriteString("return {\n")
for i := 0; i < entries; i++ {
fmt.Fprintf(&b, " [%q] = %q,\n",
fmt.Sprintf("ui.label.section_%d.key_%d", i/100, i),
fmt.Sprintf("Translation %d.", i),
)
}
b.WriteString("}\n")
o := New(Config{Preset: PresetMinify, Seed: 1})
out, err := o.Obfuscate(b.String())
if err != nil {
t.Fatalf("Obfuscate large table (%d entries): %v", entries, err)
}
if out == "" {
t.Fatal("empty output")
}
}
// TestObfuscate_ScientificNumberLiteral covers two number-literal forms
// that exposed bugs in our wrapper:
//
// - "5e3" (no decimal point) hits a gopher-lua tonumber quirk: it
// returns nil for any "NNNeKK" form lacking a "." between mantissa and
// exponent. bootstrap.lua now shims tonumber to retry with ".0e".
// - "1e500" parses to +Inf and overflows arithmetic inside the
// NumbersToExpressions generators; those generators now bail when the
// round-trip via tostring/tonumber produces nil.
func TestObfuscate_ScientificNumberLiteral(t *testing.T) {
cases := []struct {
name, src string
}{
{"plain_scientific", `local KILLS = 5e3; local DAY = 86400; return KILLS * DAY`},
{"extreme_literal", `local huge = 1e500; local norm = 4294967295; return huge + norm`},
{"big_hex_literal", `local mask = 0xFFFFFFFFFFFFFFFF; return mask`},
{"big_binary_literal", `local mask = 0b1111111111111111111111111111111111111111111111111111111111111111; return mask`},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
o := New(Config{Preset: PresetMedium, Seed: 1})
out, err := o.Obfuscate(tc.src)
if err != nil {
t.Fatalf("Obfuscate %s: %v", tc.name, err)
}
if out == "" {
t.Fatal("empty output")
}
})
}
}
// TestObfuscate_ContinueKeyword covers the LuaJIT/OTClient `continue`
// extension as a soft keyword in Lua51 mode. Upstream Prometheus only
// accepts continue when LuaVersion=LuaU; we accept it in Lua51 too, but
// only when followed by a statement boundary, so identifiers like
// obj.continue and method names `function X:continue()` still parse.
func TestObfuscate_ContinueKeyword(t *testing.T) {
cases := []struct {
name, src string
}{
{
"continue_statement",
`
for i = 1, 10 do
if i % 2 == 0 then
continue
end
print(i)
end
`,
},
{
"continue_as_method_name",
`
local obj = {}
function obj:continue()
return self.continue_value or 0
end
obj.continue_value = 1
return obj:continue() + obj.continue_value
`,
},
{
"continue_with_trailing_semicolon",
`for i = 1, 5 do if i == 3 then continue; end print(i) end`,
},
{
// goto/label support inside a loop body (LuaJIT continue idiom).
"goto_label_in_loop",
`
for i = 1, 5 do
if i == 2 then goto continue end
if i == 3 then goto continue end
print(i)
::continue::
end
`,
},
{
// goto/label used for function-level early exit. This is the
// pattern in changemove.lua: ::continue:: is not at end of
// function and is not bound to a loop, so this MUST be parsed
// as actual goto/label (cannot be rewritten to `continue`).
"goto_label_function_early_exit",
`
function onItemGrabbed(self, mb)
local x = nil
if mb ~= 1 then goto continue end
x = compute()
if not x then goto continue end
process(x)
::continue::
cleanup()
return true
end
`,
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
o := New(Config{Preset: PresetMedium, Seed: 1})
out, err := o.Obfuscate(tc.src)
if err != nil {
t.Fatalf("Obfuscate %s: %v", tc.name, err)
}
if out == "" {
t.Fatal("empty output")
}
})
}
}
func TestObfuscate_Concurrent(t *testing.T) {
o := New(Config{Preset: PresetWeak, Seed: 7})
const n = 8
var wg sync.WaitGroup
errs := make(chan error, n)
for i := 0; i < n; i++ {
wg.Add(1)
go func() {
defer wg.Done()
_, err := o.Obfuscate(helloLua)
errs <- err
}()
}
wg.Wait()
close(errs)
for err := range errs {
if err != nil {
t.Errorf("concurrent obfuscate: %v", err)
}
}
}