Skip to content

Magento/Framework/Reflection/TypeProcessor:getParamType fails parsing docblock with Windows line endings #7745

@tim-reynolds

Description

@tim-reynolds

Relates to: #2417

The class Magento/Framework/Reflection/TypeProcessor has a function:

getParamType

https://github.com/magento/magento2/blob/develop/lib/internal/Magento/Framework/Reflection/TypeProcessor.php#L543

This function uses a regular expression to parse out parameter types from the docblock of functions to extract the true type of a parameter. This is especially important for interfaces such as:

https://github.com/magento/magento2/blob/develop/app/code/Magento/Sales/Api/ShipOrderInterface.php#L30

Which put the type inline as 'array' for $items (and others).

This regular expression assumes that the source files all have Unix style line endings (\n) and not Windows style line endings (\r\n). Although this typically is the case, for whatever reason there was one file in my system that had Windows style line endings, causing the regular expression to fail.

Preconditions

  1. Magento 2: Any version
  2. PHP: Any version

Steps to reproduce

  1. Convert the line endings for \Magento\Sales\Api\ShipOrderInterface.php to Windows style (\r\n)
  2. Visit any page that would generate a WSDL or Rest API interface. Ex: http://yoursite.com/swagger/

Expected result

  1. You get a response back

Actual result

  1. You will get an error. Logs are on issue 2417.

Cause

Regular expression not matching potential Windows style line endings

Solution

Convert the regular expression:

$pattern = "/\@param\s+([\w\\\_]+\[\])\s+\\\${$param->getName()}\n/";

To:

$pattern = "/\@param\s+([\w\\\_]+\[\])\s+\\\${$param->getName()}\r?\n/";

Optionally, since we are parsing free-form text, we should consiver being a bit more permissive and adding support for accidental whitespace after the variable name, so we could use:

$pattern = "/\@param\s+([\w\\\_]+\[\])\s+\\\${$param->getName()}\s*\r?\n/";

Finally, I have seen phpdoc where the parameter name appears before the type, although I know this isn't standard, but should we consider supporting that with a second regular expression? That expression would likely be:

$pattern = "/\@param\s+\\\${$param->getName()}([\w\\\_]+\[\])\s*\r?\n/";

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions