Files
codeql/go/ql/test/query-tests/InconsistentCode/MissingErrorCheck/tests.go
2022-05-20 10:07:19 -07:00

247 lines
3.8 KiB
Go

package test
import (
"errors"
"fmt"
"os"
)
func returnsNonNil(input int) (*int, error) {
newp := new(int)
*newp = 5
if input%2 == 0 {
return newp, nil
} else {
return newp, errors.New("oh no")
}
}
func userDefinedDie() {
os.Exit(1)
}
func makesCheckUsingSwitch(fname string) {
result, err := os.Open(fname)
switch {
case len(os.Args) >= 3:
fmt.Println("Too many args")
return
case err != nil:
fmt.Println("Open failed")
return
}
fmt.Printf("Opened: %v\n", *result) // OK
}
func definesValueInIf(fname string) {
var result *os.File
var err error
if result, err = os.Open(fname); err != nil {
return
}
fmt.Printf("Opened: %v\n", *result) // OK
}
func missingCheckMayFail(fname string) {
result, err := os.Open(fname)
fmt.Printf("Opened: %v\n", *result) // NOT OK
fmt.Printf("%v\n", err) // use err
}
func missingCheckSafe(input int) {
result, err := returnsNonNil(input)
fmt.Printf("Got: %d\n", *result) // OK
fmt.Printf("%v\n", err) // use err
}
func usesUserExitFn(fname string) {
result, err := os.Open(fname)
if err != nil {
userDefinedDie()
}
fmt.Printf("Opened: %v\n", *result) // OK
fmt.Printf("%v\n", err) // use err
}
func userTestFn(e error) bool {
return e != nil
}
func usesUserTestFn(fname string) {
result, err := os.Open(fname)
if userTestFn(err) {
return
}
fmt.Printf("Opened: %v\n", *result) // OK
fmt.Printf("%v\n", err) // use err
}
func userRequireFn(e error) {
if e != nil {
os.Exit(1)
}
}
func usesUserRequireFn(fname string) {
result, err := os.Open(fname)
userRequireFn(err)
fmt.Printf("Opened: %v\n", *result) // OK
fmt.Printf("%v\n", err) // use err
}
func userPtrTestFn(ptr *os.File) bool {
return ptr != nil
}
func usesUserPtrTestFn(fname string) {
result, err := os.Open(fname)
if userPtrTestFn(result) {
return
}
fmt.Printf("Opened: %v\n", *result) // OK
fmt.Printf("%v\n", err) // use err
}
func userPtrRequireFn(ptr *os.File) {
if ptr != nil {
os.Exit(1)
}
}
func usesUserPtrRequireFn(fname string) {
result, err := os.Open(fname)
userPtrRequireFn(result)
fmt.Printf("Opened: %v\n", *result) // OK
fmt.Printf("%v\n", err) // use err
}
func reusesErrorVar(fname string) {
result, err := os.Open(fname)
if err == nil {
_, err = os.Open(fname)
}
if err != nil {
return
}
fmt.Printf("Opened: %v\n", *result) // OK
fmt.Printf("%v\n", err) // use err
}
func neverReallyErrors() (*int, error) {
newp := new(int)
*newp = 1
return newp, nil
}
func callsNeverReallyErrors() {
result, err := neverReallyErrors()
fmt.Printf("Got: %d\n", *result) // OK
fmt.Printf("%v\n", err) // use err
}
func checksErrorViaPhiNode(fname string) {
// Note 'result' must not be forwarded via a phi;
// the deref has to be of exactly the definition
// we're investigating, whereas the error check can
// be of any downstream SSA or ordinary copy.
result, err := os.Open(fname)
if len(fname)%3 == 0 {
_, err = os.Open(fname)
}
if err != nil {
return
}
fmt.Printf("Opened: %v\n", *result) // OK
fmt.Printf("%v\n", err) // use err
}
func checksErrorViaCopy(fname string) {
var result *os.File
var err error
var err2 error
result, err2 = os.Open(fname)
err = err2
if err != nil {
return
}
fmt.Printf("Opened: %v\n", *result) // OK
fmt.Printf("%v\n", err) // use err
}
type myError struct {
field int
}
// Implement error interface:
func (err *myError) Error() string {
return "myError"
}
func returnsMyError(input int) (*int, *myError) {
if input%2 == 0 {
newp := new(int)
*newp = 5
return newp, nil
} else {
return nil, &myError{}
}
}
func mishandlesMyError(input int) {
result, err := returnsMyError(input)
fmt.Printf("Got: %d\n", *result) // NOT OK
fmt.Printf("%v\n", err) // use err
}