github.com/google/capslock@v0.2.3-0.20240517042941-dac19fc347c0/testpkgs/indirectcalls/indirectcalls.go (about) 1 // Copyright 2023 Google LLC 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file or at 5 // https://developers.google.com/open-source/licenses/bsd 6 7 // Package indirectcalls is used for testing. 8 package indirectcalls 9 10 import ( 11 "io" 12 "os" 13 ) 14 15 // CallOs calls a function in os. 16 func CallOs() int { 17 return os.Getuid() + 42 18 } 19 20 // CallOsViaFuncVariable calls a function in os via a variable with func type. 21 func CallOsViaFuncVariable() int { 22 var f func() int = CallOs 23 return f() + 100 24 } 25 26 // CallOsViaStructField calls a function in os via a struct field with func 27 // type. 28 func CallOsViaStructField() int { 29 type foo struct { 30 f func() int 31 } 32 var f foo 33 f.f = CallOs 34 return f.f() + 123 35 } 36 37 type myInterface interface { 38 foo() int 39 } 40 41 type myStruct struct{} 42 43 func (m myStruct) foo() int { 44 return CallOs() + 456 45 } 46 47 type myOtherStruct float32 48 49 func (m myOtherStruct) foo() int { 50 return -1e6 51 } 52 53 var m1, m2 myInterface 54 55 func init() { 56 m1, m2 = myStruct{}, myOtherStruct(1) 57 } 58 59 // CallOsViaInterfaceMethod calls a function in os via an interface method. 60 func CallOsViaInterfaceMethod() int { 61 return m1.foo() / 2 62 } 63 64 // ShouldHaveNoCapabilities calls the interface function myInterface.Foo. 65 // One of the concrete types which implement myInterface has a Foo method 66 // which calls an interesting function in os, but the particular variable used 67 // here can not have that type, so a precise-enough analysis would report that 68 // this function has no interesting capabilities. 69 func ShouldHaveNoCapabilities() int { 70 return m2.foo() * 2 71 } 72 73 func maybeChown(r io.Reader) { 74 if c, ok := r.(interface{ Chown(int, int) error }); ok { 75 c.Chown(42, 42) 76 } 77 } 78 79 // AccessMethodViaTypeAssertion calls (*os.File).Chown by passing an 80 // io.Reader with dynamic type (*os.File) to maybeChown. 81 func AccessMethodViaTypeAssertion() { 82 var r io.Reader = os.Stderr 83 maybeChown(r) 84 } 85 86 // MaybeChmod would call (*os.File).Chmod if its io.Reader parameter 87 // had dynamic type (*os.File). 88 func MaybeChmod(r io.Reader) { 89 if c, ok := r.(interface{ Chmod(os.FileMode) error }); ok { 90 c.Chmod(0) 91 } 92 }