Skip to content

Commit

Permalink
new tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Hidanio committed Feb 16, 2025
1 parent 05bbbd2 commit 7f516ba
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/linter/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,7 @@ func (b *blockWalker) checkNullSafetyCallArgsF(args []ir.Node, fn meta.FuncInfo)
}

// if something like this: function requestRestart($stream_id); requestRestart($stream_id, $res);
if i > len(fn.Params)-1 {
if i > len(fn.Params)-1 && !haveVariadic {
return
}

Expand Down
155 changes: 155 additions & 0 deletions src/tests/checkers/null_safety_test.go
Original file line number Diff line number Diff line change
@@ -1 +1,156 @@
package checkers

import (
"github.com/VKCOM/noverify/src/linttest"
"testing"
)

func TestFunctionPassingNull(t *testing.T) {
test := linttest.NewSuite(t)
test.AddFile(`<?php
class A {
public string $value = 'Hello';
}
function test(A $a): void {
echo $a->value;
}
test(null);
`)
test.Expect = []string{
"null passed to non-nullable parameter a in function test",
}
test.RunAndMatch()
}

func TestPropertyFetchNullSafety(t *testing.T) {
test := linttest.NewSuite(t)
test.AddFile(`<?php
class A {
public ?B $b = null;
}
class B {
public string $value = 'Test';
}
function test(B $b): void {
echo $b->value;
}
$a = new A();
test($a->b);
`)
test.Expect = []string{
"potential null dereference when accessing property 'b'",
}
test.RunAndMatch()
}

func TestChainedPropertyAccessNullSafety(t *testing.T) {
test := linttest.NewSuite(t)
test.AddFile(`<?php
declare(strict_types=1);
class A {
public ?B $b = null;
}
class B {
public C $c;
public function __construct() {
// Initialize property c with an instance of C.
$this->c = new C();
}
}
class C {
public string $value = 'Hello';
}
/**
* Function expecting an object of class C.
*/
function test(C $c): void {
echo $c->value;
}
$a = new A();
// $a->b is null, so accessing $a->b->c leads to a potential null dereference.
test($a->b->c);
`)
test.Expect = []string{
"potential null dereference when accessing property",
}
test.RunAndMatch()
}

// After fix issue with not correct checking existing variable after unpacking - should fail
func TestListExprNullSafety(t *testing.T) {
test := linttest.NewSuite(t)
test.AddFile(`<?php
class A {
public string $value = 'Hello';
}
function test(A $a): void {
echo $a->value;
}
list($m, list($n, $o)) = [new A(), [new A(), null]];
test($m);
test($n);
test($o);
`)
test.Expect = []string{
"not null safety call in function test signature of param",
"Cannot find referenced variable $o",
"Cannot find referenced variable $n",
}
test.RunAndMatch()
}

func TestArrayDimFetchNullSafety(t *testing.T) {
test := linttest.NewSuite(t)
test.AddFile(`<?php
class A {
public string $value = 'Hello';
}
function test(A $a): void {
echo $a->value;
}
$arr = [new A(), null];
test($arr[1]);
`)
test.Expect = []string{
"potential null array access in parameter a of function test",
}
test.RunAndMatch()
}

func TestVariadicParameterNullSafety(t *testing.T) {
test := linttest.NewSuite(t)
test.AddFile(`<?php
class A {
public string $value = 'Hello';
}
/**
* Variadic function accepting only objects of class A.
*/
function testVariadic(A ...$a): void {
foreach ($a as $item) {
echo $item->value, "\n";
}
}
testVariadic(new A(), null);
`)
test.Expect = []string{
"null passed to non-nullable variadic parameter a in function testVariadic",
}
test.RunAndMatch()
}

0 comments on commit 7f516ba

Please sign in to comment.