evil.gno
1.86 Kb · 65 lines
1// Package evil is the adversarial engine of spike (a). It behaves during
2// registration and misbehaves afterwards, selected by a mode it controls.
3// Every mode is a question for the acceptance table in ../README.md.
4package evil
5
6import (
7 "strings"
8
9 "gno.land/r/g19dzk54hhsdc3gllpksuj6gu4a3e6fl8cr6rn4w/minhwa/spike/registry"
10)
11
12// The modes. Render chooses its behaviour from the seed so that each attack
13// can be triggered by a plain qeval without changing evil's state.
14const (
15 SeedWrite = "write" // write through a pointer into registry state
16 SeedBump = "bump" // call registry's non-crossing mutator
17 SeedPanic = "panic" // abort the read
18 SeedLoop = "loop" // burn the query gas
19 SeedHuge = "huge" // return an oversized output
20 SeedScript = "script" // return active SVG content
21)
22
23type impl struct{}
24
25// mutated flips Render's output for the sample seed after registration, to
26// show that a public engine realm with state can change its art (the
27// fingerprint check is the only on-chain detector).
28var mutated bool
29
30func (impl) Name() string { return "spike-evil" }
31
32func (impl) Render(seed string) string {
33 switch seed {
34 case registry.SampleSeed:
35 if mutated {
36 return "<svg>changed</svg>"
37 }
38 return "<svg>sample</svg>"
39 case SeedWrite:
40 registry.SharedBoard().Count = 999
41 return "<svg>wrote</svg>"
42 case SeedBump:
43 registry.UnsafeBump()
44 return "<svg>bumped</svg>"
45 case SeedPanic:
46 panic("evil: render refused")
47 case SeedLoop:
48 for {
49 }
50 case SeedHuge:
51 return "<svg>" + strings.Repeat("A", 1<<20) + "</svg>"
52 case SeedScript:
53 return `<svg xmlns="http://www.w3.org/2000/svg"><script>alert(1)</script></svg>`
54 }
55 return "<svg>" + seed + "</svg>"
56}
57
58func Register(cur realm) string {
59 return registry.Register(cross(cur), impl{})
60}
61
62// Mutate changes the sample output after registration (evil's own state).
63func Mutate(cur realm) {
64 mutated = true
65}