|
@@ -11,7 +11,7 @@
|
|
|
>
|
|
>
|
|
|
> Each finding is referenced as **F<N>** for later citation.
|
|
> Each finding is referenced as **F<N>** for later citation.
|
|
|
>
|
|
>
|
|
|
-> **Findings rolled up:** 5 sev-3 (5 fixed, 0 open), 27 sev-2 (27 fixed, 0 open), 42 sev-1 (18 fixed, 24 open).
|
|
|
|
|
|
|
+> **Findings rolled up:** 5 sev-3 (5 fixed, 0 open), 27 sev-2 (27 fixed, 0 open), 42 sev-1 (19 fixed, 23 open).
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
@@ -1686,6 +1686,19 @@
|
|
|
`array_filter($groupIds, 'is_string')` to make the contract
|
|
`array_filter($groupIds, 'is_string')` to make the contract
|
|
|
explicit.
|
|
explicit.
|
|
|
- **Severity: 1**
|
|
- **Severity: 1**
|
|
|
|
|
+- **Status:** Fixed. `RoleMappingRepository::resolveRole` now does
|
|
|
|
|
+ `array_values(array_filter($groupIds, 'is_string'))` as the first
|
|
|
|
|
+ step, so the `count($groupIds)` placeholder generation and the
|
|
|
|
|
+ bind-list always agree even when a future caller passes a mixed
|
|
|
|
|
+ array, a hash with skipped indexes, or anything else that violates
|
|
|
|
|
+ the PHPDoc `list<string>` contract. After filtering, the empty
|
|
|
|
|
+ case correctly falls back to the default role. Regression tests
|
|
|
|
|
+ in `api/tests/Integration/Auth/RoleMappingRepositoryTest.php`:
|
|
|
|
|
+ - happy-path highest-role-resolution and default-fallback,
|
|
|
|
|
+ - non-string entries are filtered, retaining valid string IDs,
|
|
|
|
|
+ - all-non-string list collapses to the default,
|
|
|
|
|
+ - a hash with non-contiguous keys (`[5 => 'group-x', 12 => '…']`)
|
|
|
|
|
+ is re-keyed and the IN clause still works.
|
|
|
|
|
|
|
|
### F52 — Reporter / consumer / category `name`/`reason` accept control characters
|
|
### F52 — Reporter / consumer / category `name`/`reason` accept control characters
|
|
|
- **Files:** `api/src/Application/Admin/ReportersController.php:69-72`,
|
|
- **Files:** `api/src/Application/Admin/ReportersController.php:69-72`,
|