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  }