Skip to content

Commit 16a9bd9

Browse files
authored
Merge pull request #17 from Mutated1994/master
fix: Fix panic when calling PatchGuard.Restore
2 parents d792ef7 + d203a03 commit 16a9bd9

File tree

7 files changed

+59
-11
lines changed

7 files changed

+59
-11
lines changed

examples/patch_func.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ func patchFunc() {
2020
fmt.Println("unpatch, then output:")
2121
heyHey()
2222

23+
patchGuard.Restore()
24+
fmt.Println("restore, then output:")
25+
heyHey()
26+
27+
patchGuard.Unpatch()
28+
fmt.Println("unpatch, then output:")
29+
heyHey()
30+
2331
fmt.Println()
2432
}
2533

examples/patch_func_symbol.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ func patchFuncSymbol() {
2020
fmt.Println("unpatch, then output:")
2121
heyHeyHey()
2222

23+
patchGuard.Restore()
24+
fmt.Println("restore, then output:")
25+
heyHeyHey()
26+
27+
patchGuard.Unpatch()
28+
fmt.Println("unpatch, then output:")
29+
heyHeyHey()
30+
2331
fmt.Println()
2432
}
2533

examples/patch_instance_func.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,13 @@ func patchInstanceFunc() {
2828
fmt.Println("unpatch, then output:")
2929
p.speak()
3030

31+
patchGuard.Restore()
32+
fmt.Println("restore, then output:")
33+
p.speak()
34+
35+
patchGuard.Unpatch()
36+
fmt.Println("unpatch, then output:")
37+
p.speak()
38+
3139
fmt.Println()
3240
}

examples/patch_instance_func_symbol.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,13 @@ func patchInstanceFuncSymbol() {
2323
fmt.Println("unpatch, then output:")
2424
p.speak()
2525

26+
patchGuard.Restore()
27+
fmt.Println("restore, then output:")
28+
p.speak()
29+
30+
patchGuard.Unpatch()
31+
fmt.Println("unpatch, then output:")
32+
p.speak()
33+
2634
fmt.Println()
2735
}

examples/patch_struct_method.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,13 @@ func patchStructMethod() {
3434
fmt.Println("unpatch, then output:")
3535
fmt.Println(f.MyFunc(nil))
3636

37+
patchGuard.Restore()
38+
fmt.Println("restore, then output:")
39+
fmt.Println(f.MyFunc(nil))
40+
41+
patchGuard.Unpatch()
42+
fmt.Println("unpatch, then output:")
43+
fmt.Println(f.MyFunc(nil))
44+
3745
fmt.Println()
38-
}
46+
}

examples/patch_struct_method_symbol.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ func patchStructMethodSymbol() {
2424
fmt.Println("unpatch, then output:")
2525
fmt.Println(f.MyFunc(nil))
2626

27+
patchGuard.Restore()
28+
fmt.Println("restore, then output:")
29+
fmt.Println(f.MyFunc(nil))
30+
31+
patchGuard.Unpatch()
32+
fmt.Println("unpatch, then output:")
33+
fmt.Println(f.MyFunc(nil))
34+
2735
fmt.Println()
2836
}
29-

internal/bouk/monkey.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,31 +32,32 @@ func getPtr(v reflect.Value) unsafe.Pointer {
3232
type PatchGuard struct {
3333
target reflect.Value
3434
replacement reflect.Value
35+
isSymbol bool
3536
}
3637

3738
func (g *PatchGuard) Unpatch() {
3839
unpatchValue(g.target)
3940
}
4041

4142
func (g *PatchGuard) Restore() {
42-
patchValue(g.target, g.replacement)
43+
patchValue(g.target, g.replacement, g.isSymbol)
4344
}
4445

4546
// Patch replaces a function with another
4647
func Patch(target, replacement interface{}) *PatchGuard {
4748
t := reflect.ValueOf(target)
4849
r := reflect.ValueOf(replacement)
49-
patchValue(t, r)
50+
patchValue(t, r, false)
5051

51-
return &PatchGuard{t, r}
52+
return &PatchGuard{t, r, false}
5253
}
5354

5455
func PatchSymbol(target, replacement interface{}) *PatchGuard {
5556
t := reflect.ValueOf(target)
5657
r := reflect.ValueOf(replacement)
5758
patchSymbolValue(t, r)
5859

59-
return &PatchGuard{t, r}
60+
return &PatchGuard{t, r, true}
6061
}
6162

6263
// PatchInstanceMethod replaces an instance method methodName for the type target with replacement
@@ -67,24 +68,24 @@ func PatchInstanceMethod(target reflect.Type, methodName string, replacement int
6768
panic(fmt.Sprintf("unknown method %s", methodName))
6869
}
6970
r := reflect.ValueOf(replacement)
70-
patchValue(m.Func, r)
71+
patchValue(m.Func, r, false)
7172

72-
return &PatchGuard{m.Func, r}
73+
return &PatchGuard{m.Func, r, false}
7374
}
7475

75-
func patchValue(target, replacement reflect.Value) {
76+
func patchValue(target, replacement reflect.Value, isSymbol bool) {
7677
lock.Lock()
7778
defer lock.Unlock()
7879

79-
if target.Kind() != reflect.Func {
80+
if !isSymbol && target.Kind() != reflect.Func {
8081
panic("target has to be a Func")
8182
}
8283

8384
if replacement.Kind() != reflect.Func {
8485
panic("replacement has to be a Func")
8586
}
8687

87-
if target.Type() != replacement.Type() {
88+
if !isSymbol && target.Type() != replacement.Type() {
8889
panic(fmt.Sprintf("target and replacement have to have the same type %s != %s", target.Type(), replacement.Type()))
8990
}
9091

0 commit comments

Comments
 (0)