From 872e88c4d90fc01d01e6bd4d72cd38221685df4f Mon Sep 17 00:00:00 2001 From: Daniel Redondo Date: Sun, 10 May 2020 12:34:43 +0200 Subject: [PATCH] Adds support for patching value struct (#5) * adds support for patching value struct * add go versions to the matrix --- .github/workflows/go.yml | 2 +- patcher.go | 5 +++-- patcher_test.go | 31 +++++++++++++++++++++++++++++++ patcher_unsupported.go | 2 +- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 2288f88..219a0a4 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -5,7 +5,7 @@ jobs: name: Test strategy: matrix: - go_version: [1.12, 1.13] + go_version: [1.11, 1.12, 1.13, 1.14] os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} steps: diff --git a/patcher.go b/patcher.go index 8c3fafb..ffe89ef 100644 --- a/patcher.go +++ b/patcher.go @@ -42,10 +42,11 @@ func PatchMethod(target, redirection interface{}) (*Patch, error) { return patch, nil } func PatchInstanceMethodByName(target reflect.Type, methodName string, redirection interface{}) (*Patch, error) { - if target.Kind() == reflect.Struct { + method, ok := target.MethodByName(methodName) + if !ok && target.Kind() == reflect.Struct { target = reflect.PtrTo(target) + method, ok = target.MethodByName(methodName) } - method, ok := target.MethodByName(methodName) if !ok { return nil, errors.New(fmt.Sprintf("Method '%v' not found", methodName)) } diff --git a/patcher_test.go b/patcher_test.go index 47e6e4e..f34f24a 100644 --- a/patcher_test.go +++ b/patcher_test.go @@ -19,6 +19,11 @@ func (s *myStruct) Method() int { return 1 } +//go:noinline +func (s myStruct) ValueMethod() int { + return 1 +} + func TestPatcher(t *testing.T) { patch, err := PatchMethod(methodA, methodB) if err != nil { @@ -62,3 +67,29 @@ func TestInstancePatcher(t *testing.T) { t.Fatal("The unpatch did not work") } } + +func TestInstanceValuePatcher(t *testing.T) { + mStruct := myStruct{} + + var patch *Patch + var err error + patch, err = PatchInstanceMethodByName(reflect.TypeOf(mStruct), "ValueMethod", func(m myStruct) int { + patch.Unpatch() + defer patch.Patch() + return 41 + m.Method() + }) + if err != nil { + t.Fatal(err) + } + + if mStruct.ValueMethod() != 42 { + t.Fatal("The patch did not work") + } + err = patch.Unpatch() + if err != nil { + t.Fatal(err) + } + if mStruct.ValueMethod() != 1 { + t.Fatal("The unpatch did not work") + } +} diff --git a/patcher_unsupported.go b/patcher_unsupported.go index 8a796fd..a2fe4b7 100644 --- a/patcher_unsupported.go +++ b/patcher_unsupported.go @@ -12,4 +12,4 @@ import ( // Gets the jump function rewrite bytes func getJumpFuncBytes(to uintptr) ([]byte, error) { return nil, errors.New(fmt.Sprintf("Unsupported architecture: %s", runtime.GOARCH)) -} \ No newline at end of file +}