Skip to content

v3.15.5

Choose a tag to compare

@alies-dev alies-dev released this 18 Aug 14:42
2585063

Taint precision and Eloquent type narrowing. Two taint fixes remove a duplicate finding and close a missed SQL injection, and four type fixes sharpen inference on facades, collections, and the query builder.

Fixes

  • Restore plugin facade stub precedence over Laravel's generated @method tags, so templated facade methods resolve their real return type (#1370)
 $value = Cache::remember('key', 60, fn (): User => User::first());
-// mixed — the generated @method tag outranked the plugin's stub
+// User
  • Narrow groupBy() and keyBy() keys for model columns instead of widening to array-key (#1369)
 $byId = User::all()->keyBy('id');
-// Collection<array-key, User>
+// Collection<int, User>
  • Type the chunkById() callback like chunk(), so the chunk is a templated collection rather than mixed (#1373)
 Article::query()->chunkById(100, function ($chunk) { ... });
-// $chunk: mixed
+// $chunk: Collection<int, Article>
  • Accept Laravel 13's fourth $fetchUsing argument on DB::select(), DB::selectResultSets(), DB::cursor(), and their Connection counterparts, while keeping the three-argument signature an error on Laravel 12 (#1374)
 DB::cursor('select * from users', [], true, [PDO::FETCH_ASSOC]);
-// TooManyArguments — the stub declared three parameters
+// accepted on Laravel 13; still TooManyArguments on Laravel 12

Row types follow the fetch mode, so a custom $fetchUsing no longer claims stdClass:

 $rows = DB::cursor('select 1');                              // Generator<int, stdClass>
 $assoc = DB::cursor('select 1', [], true, [PDO::FETCH_ASSOC]);
-// Generator<int, stdClass>
+// Generator<int, mixed>
  • 🛡️ Report a tainted view name as TaintedInclude only, not also TaintedFile (#1358). A view name selects which template executes; it cannot reach an arbitrary path, because the view finder rewrites . to / and appends a fixed extension
  • 🛡️ Key WhereColumnTaintHandler's removal bridge on the AST node itself rather than spl_object_id, closing a missed SQL injection (#1366). Psalm frees foreign ASTs mid-file, so a reissued object handle could hit a stale record and strip sql taint from an unrelated expression
  • Ship the Psalm cache in the generated CI template, pass both thread flags, and install igbinary (#1347)

Full Changelog: v3.15.4...v3.15.5