Skip to content

Unable to extend UrlScript #187

Closed

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.

Activity

  1. jakubboucek commented on Nov 14, 2020

    @jakubboucek
    ContributorAuthor

    Update: Suggested solution doesn't works :-/

  2. jakubboucek commented on Nov 14, 2020

    @jakubboucek
    ContributorAuthor

    This code is works very well but ugly:

    public function withPath(string $path, string $scriptPath = '')
    {
        $dolly = clone $this;
        $dolly->scriptPath = $scriptPath;
        return call_user_func([$dolly, '\Nette\Http\UrlImmutable::withPath'], $path);
    }
  3. added a commit that references this issue on Nov 16, 2020
  4. added a commit that references this issue on Dec 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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