blob: 6482b7194599205c349b27075e392588ec60135c [file] [log] [blame]
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
rules:
- id: lock_not_unlocked
message: |
Lock $LOCK not unlocked on branch with $COND
languages: [go]
severity: WARNING
patterns:
- pattern: |
$LOCK.Lock()
...
if $COND {
...
return ...
}
# manual unlock before return
- pattern-not: |
$LOCK.Lock()
...
if $COND {
...
$LOCK.Unlock()
...
return ...
}
- pattern-not: |
$LOCK.Lock()
...
$LOCK.Unlock()
...
if $COND {
...
return ...
}
# manual unlock with release function
- pattern-not: |
$LOCK.Lock()
...
$UNLOCKFN = $LOCK.Unlock
...
if $COND {
...
$UNLOCKFN()
...
return ...
}
- pattern-not: |
$LOCK.Lock()
...
$UNLOCKFN := $LOCK.Unlock
...
if $COND {
...
$UNLOCKFN()
...
return ...
}
# defered unlock
- pattern-not: |
$LOCK.Lock()
...
defer $LOCK.Unlock()
...
if $COND {
...
return ...
}
- pattern-not: |
$LOCK.Lock()
...
if $COND {
...
defer $LOCK.Unlock()
...
return ...
}
- pattern-not: |
$LOCK.Lock()
...
defer func(){
...
$LOCK.Unlock()
...
}()
...
if $COND {
...
return ...
}
# deferred unlock with release function
- pattern-not: |
$LOCK.Lock()
...
$UNLOCKFN := $LOCK.Unlock
...
defer func() {
...
$UNLOCKFN()
...
}()
...
if $COND {
...
return ...
}
- pattern-not: |
$LOCK.Lock()
...
$UNLOCKFN = $LOCK.Unlock
...
defer func() {
...
$UNLOCKFN()
...
}()
...
if $COND {
...
return ...
}
# variation where defer is called first,
# unlock function is changed afterwards
- pattern-not-inside: |
defer func() {
...
$UNLOCKFN()
...
}()
...
$LOCK.Lock()
...
$UNLOCKFN = $LOCK.Unlock
...
if $COND {
...
return ...
}
# variation where defer is called previously, lock is reacquired
# maybe include the Unlock call here?
- pattern-not-inside: |
defer $LOCK.Unlock()
...
$LOCK.Lock()
...
if $COND {
...
return ...
}
- id: read_lock_not_unlocked
message: |
Lock $LOCK not unlocked on branch with $COND
languages: [go]
severity: WARNING
patterns:
- pattern: |
$LOCK.RLock()
...
if $COND {
...
return ...
}
# manual unlock before return
- pattern-not: |
$LOCK.RLock()
...
if $COND {
...
$LOCK.RUnlock()
...
return ...
}
- pattern-not: |
$LOCK.RLock()
...
$LOCK.RUnlock()
...
if $COND {
...
return ...
}
# manual unlock with release function
- pattern-not: |
$LOCK.RLock()
...
$UNLOCKFN = $LOCK.RUnlock
...
if $COND {
...
$UNLOCKFN()
...
return ...
}
- pattern-not: |
$LOCK.RLock()
...
$UNLOCKFN := $LOCK.RUnlock
...
if $COND {
...
$UNLOCKFN()
...
return ...
}
# defered unlock
- pattern-not: |
$LOCK.RLock()
...
defer $LOCK.RUnlock()
...
if $COND {
...
return ...
}
- pattern-not: |
$LOCK.RLock()
...
if $COND {
...
defer $LOCK.RUnlock()
...
return ...
}
- pattern-not: |
$LOCK.RLock()
...
defer func(){
...
$LOCK.RUnlock()
...
}()
...
if $COND {
...
return ...
}
# deferred unlock with release function
- pattern-not: |
$LOCK.RLock()
...
$UNLOCKFN := $LOCK.RUnlock
...
defer func() {
...
$UNLOCKFN()
...
}()
...
if $COND {
...
return ...
}
- pattern-not: |
$LOCK.RLock()
...
$UNLOCKFN = $LOCK.RUnlock
...
defer func() {
...
$UNLOCKFN()
...
}()
...
if $COND {
...
return ...
}
# variation where defer is called first,
# unlock function is changed afterwards
- pattern-not-inside: |
defer func() {
...
$UNLOCKFN()
...
}()
...
$LOCK.RLock()
...
$UNLOCKFN = $LOCK.RUnlock
...
if $COND {
...
return ...
}
# variation where defer is called previously, lock is reacquired
# maybe include the Unlock call here?
- pattern-not-inside: |
defer $LOCK.RUnlock()
...
$LOCK.RLock()
...
if $COND {
...
return ...
}