Skip to content

Commit

Permalink
fixed panic by variadic for checkConstFetchNullSafety
Browse files Browse the repository at this point in the history
  • Loading branch information
Hidanio committed Feb 13, 2025
1 parent c9ca8e5 commit aa69d8b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 9 deletions.
46 changes: 37 additions & 9 deletions src/linter/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -1028,27 +1028,35 @@ func (b *blockWalker) handleIssetDimFetch(e *ir.ArrayDimFetchExpr) {
}

func (b *blockWalker) checkNullSafetyCallArgsF(args []ir.Node, fn meta.FuncInfo) {
if fn.Params == nil || fn.Name == "" {
return
}
haveVariadic := enoughArgs(args, fn)

for i, arg := range args {
if arg == nil {
continue
}
switch a := arg.(*ir.Argument).Expr.(type) {
case *ir.SimpleVar:
b.checkSimpleVarNullSafety(arg, fn, i, a)
// b.checkSimpleVarNullSafety(arg, fn, i, a, haveVariadic)

case *ir.ConstFetchExpr:
b.checkConstFetchNullSafety(arg, fn, i, a)
b.checkConstFetchNullSafety(arg, fn, i, a, haveVariadic)

case *ir.ArrayDimFetchExpr:
b.checkArrayDimFetchNullSafety(arg, fn, i, a)
// b.checkArrayDimFetchNullSafety(arg, fn, i, a, haveVariadic)

case *ir.ListExpr:
b.checkListExprNullSafety(arg, fn, i, a)
b.checkListExprNullSafety(arg, fn, i, a, haveVariadic)

case *ir.PropertyFetchExpr:
b.checkPropertyFetchNullSafety(a)
}
}
}

func (b *blockWalker) checkSimpleVarNullSafety(arg ir.Node, fn meta.FuncInfo, paramIndex int, variable *ir.SimpleVar) {
func (b *blockWalker) checkSimpleVarNullSafety(arg ir.Node, fn meta.FuncInfo, paramIndex int, variable *ir.SimpleVar, haveVariadic bool) {

Check failure on line 1059 in src/linter/block.go

View workflow job for this annotation

GitHub Actions / linter

func `(*blockWalker).checkSimpleVarNullSafety` is unused (unused)
varInfo, ok := b.ctx.sc.GetVar(variable)

if !ok {
Expand All @@ -1063,18 +1071,38 @@ func (b *blockWalker) checkSimpleVarNullSafety(arg ir.Node, fn meta.FuncInfo, pa
}
}

func (b *blockWalker) checkConstFetchNullSafety(arg ir.Node, fn meta.FuncInfo, paramIndex int, constExpr *ir.ConstFetchExpr) {
func (b *blockWalker) checkConstFetchNullSafety(arg ir.Node, fn meta.FuncInfo, paramIndex int, constExpr *ir.ConstFetchExpr, haveVariadic bool) {
constVal := constExpr.Constant.Value
isNull := constVal == "null"

if haveVariadic {
// If the parameter is outside the declared parameters, we check the latter as a variable
if paramIndex >= len(fn.Params)-1 {
lastParam := fn.Params[len(fn.Params)-1] // last param (variadic ...args)
if types.IsTypeMixed(lastParam.Typ) {
return
}

paramAllowsNull := types.IsTypeNullable(lastParam.Typ)
if isNull && !paramAllowsNull {
b.report(arg, LevelError, "notNullSafety",
"null passed to non-nullable variadic parameter %s in function %s",
lastParam.Name, fn.Name)
}
return
}
}

paramAllowsNull := types.IsTypeNullable(fn.Params[paramIndex].Typ)
if isNull && !paramAllowsNull {
b.report(arg, LevelError, "notNullSafety", "null passed to non-nullable parameter %s in function %s", fn.Params[paramIndex].Name, fn.Name)
b.report(arg, LevelError, "notNullSafety",
"null passed to non-nullable parameter %s in function %s",
fn.Params[paramIndex].Name, fn.Name)
}
}

// TODO: we don't know type of each element without phpDoc, it will be mixed
func (b *blockWalker) checkArrayDimFetchNullSafety(arg ir.Node, fn meta.FuncInfo, paramIndex int, arrayExpr *ir.ArrayDimFetchExpr) {
func (b *blockWalker) checkArrayDimFetchNullSafety(arg ir.Node, fn meta.FuncInfo, paramIndex int, arrayExpr *ir.ArrayDimFetchExpr, haveVariadic bool) {

Check failure on line 1105 in src/linter/block.go

View workflow job for this annotation

GitHub Actions / linter

func `(*blockWalker).checkArrayDimFetchNullSafety` is unused (unused)
baseVar, ok := arrayExpr.Variable.(*ir.SimpleVar)
if !ok {
return
Expand All @@ -1091,7 +1119,7 @@ func (b *blockWalker) checkArrayDimFetchNullSafety(arg ir.Node, fn meta.FuncInfo
}

// TODO: we don't know type of each element without phpDoc, it will be mixed
func (b *blockWalker) checkListExprNullSafety(arg ir.Node, fn meta.FuncInfo, paramIndex int, listExpr *ir.ListExpr) {
func (b *blockWalker) checkListExprNullSafety(arg ir.Node, fn meta.FuncInfo, paramIndex int, listExpr *ir.ListExpr, haveVariadic bool) {
for _, item := range listExpr.Items {
if item == nil {
continue
Expand Down
10 changes: 10 additions & 0 deletions src/types/predicates.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ func IsTypeNullable(typ Map) bool {
return isNullable
}

func IsTypeMixed(typ Map) bool {
isMixed := false
typ.Iterate(func(t string) {
if strings.Contains(t, "mixed") {
isMixed = true
}
})
return isMixed
}

func Alias(s string) (string, bool) {
alias, has := aliases[s]
return alias, has
Expand Down

0 comments on commit aa69d8b

Please sign in to comment.