Skip to content

Unable to extend UrlScript #187

@jakubboucek

Description

@jakubboucek

Version: 3.0.5
PHP: 7.3.24

Bug Description

UrlScript is not work correctly when is extended. The method withPath() is calling themself recursive in infinite loop and crash with error:

Maximum function nesting level of '256' reached, aborting!

The reason is the callback parent::withPath in call_user_func() function is always called in top of descendants hierarchy context.

That's mean:

class CustomUrl extends UrlScript      parent::withPath()   call_user_func('parent::withPath')
                                         |                                    |
        +--------------------------------+------------------------------------+
        |  +-------------------------------------------------------------------------------------+
        v  v                                                                                     |
class UrlScript extends UrlImmutable   parent::withPath()   call_user_func('parent::withPath')   |
                                         |                                    |                  |       
           +-----------------------------+                                    +------------------+
           |
           v
class UrlImmutable

Steps To Reproduce

class CustomUrl extends \Nette\Http\UrlScript {}

$url = new CustomUrl('http://example.com')'
$url->withPath('foo'); // crash

Expected Behavior

Don't crash ;-)

Possible Solution

Only reason why is UrlScript using call_user_func() function to call parent method through is calling in cloned object context.

UrlScript is inherits from UrlImmuitable, UrlImmuitable::withPath() is always create clone too. When calls UrlScript::withPath() it's clone class twice.

Possible Solution is stop cloning object in UrlScript scope and rely it to UrlImmuitable.

I suggest to change method withPath() like:

public function withPath(string $path, string $scriptPath = '')
{
    $dolly = parent::withPath($path);
    $dolly->scriptPath = $scriptPath;
    return $dolly;
}

Is it my considerations right? No, isn't, see comment below.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions