mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
247 lines
3.8 KiB
Go
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
|
|
|
|
}
|