phpstan/phpstan-symfony

Remove nullable type after calling `HeaderBag::has` is breaking logic

icanhazstring opened this issue · 8 comments

With the latest release 1.2.17 removing nullable from HeaderBag::get is not working correctly.
The header can still exist but the value can be null. If that happens we now can't check for null values.

Commit in question: 7389207

foreach ($this->supportHeaders as $name) {
    if (!$request->headers->has($name)) {
        continue;
    }

    $headerValue = $request->headers->get($name);
    if ($headerValue === null) { // this will be reported as "always false" but shouldn't
        continue;
    }

    $list[] = new Attribute($name, $headerValue);
}

How does the HTTP request look like if the header is set, but the value is null?

It doesn't have to come through the means of HTTP only.
It could be set using code directly as well, in that case, a null value is possible.

Edit:
As symfony itself inside the Request object while creating the HeaderBag is allowing null values either way it could always be possible.

It happens in these lines:

public function get(string $key, string $default = null)
{
    $headers = $this->all($key);

    if (!$headers) {
        return $default;
    }

// Right here is the problem
    if (null === $headers[0]) {
        return null;
    }

    return (string) $headers[0];
}

Alright, reverting. Thanks!

Fixed by 3178f15.

/cc @franmomu

didn't know it allows null, thanks for reporting 👍 and fixing it

I think the extension from you is not completely wrong. But it would behave a little different:

  • if ::has($a) is true
  • ::get($a) will return a nullable value

But the difference is in the default value type:

  • if ::has($a) is false
  • ::get($a, 1) will return int
  • checking value against anything other than string is always false

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.