Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System::import() may return unexpected instances #2152

Closed
dmolineus opened this issue Aug 13, 2020 · 5 comments · Fixed by #2153
Closed

System::import() may return unexpected instances #2152

dmolineus opened this issue Aug 13, 2020 · 5 comments · Fixed by #2153
Labels
Milestone

Comments

@dmolineus
Copy link
Contributor

Affected version(s)

  • ^4.9.4

Description

Since #1840 a System#import() or System::importStatic() may return an unexpected instance. This is the case for the User import in Contao. How to reproduce it:

class CallbackA extends \Contao\System
{
    public function __invoke()
    {
        $this->import('Frontenduser', 'User');
        var_dump(get_class($this->User));
    }
}

class CallbackB extends \Contao\System
{
    public function __invoke()
    {
        $this->import('BackendUser', 'User');
        var_dump(get_class($this->User));
    }
}

(new CallbackA())();
(new CallbackB())();

If a third party extension imports the backend user before the frontend user is imported (e.g. through a hook), the frontend user is not used in all legacy classes. Which might lead to an invalid upload folder path in the FormFileUpload form field.

@dmolineus dmolineus changed the title System::imports may return unexpected instances System::import() may return unexpected instances Aug 13, 2020
@aschempp
Copy link
Member

I understand the problem, but I would assume it does not happen with System::importStatic() but only System::import(). Can you confirm that?

@dmolineus
Copy link
Contributor Author

dmolineus commented Aug 13, 2020

I understand the problem, but I would assume it does not happen with System::importStatic() but only System::import(). Can you confirm that?

It also happens when System::importStatic() is used. It also accesses the static cache, see https://github.com/contao/contao/pull/1840/files#diff-29552df618c525c0eb4fd5126fbe4e6fR234

var_dump(get_class(\Contao\System::importStatic(\Contao\FrontendUser::class, 'Foo')));
var_dump(get_class(\Contao\System::importStatic(\Contao\BackendUser::class, 'Foo')));

@aschempp
Copy link
Member

yes, but isn't that how importStatic() always worked? The "services" are shared across class instances?

@leofeyer leofeyer added the bug label Aug 13, 2020
@leofeyer leofeyer added this to the 4.9 milestone Aug 13, 2020
@leofeyer
Copy link
Member

I think we can fix this by using both $strClass and $strKey as cache key. Then $this->import('FrontendUser', 'User') will be stored separately from $this->import('BackendUser', 'User'). @Toflar WDYT?

@ausi
Copy link
Member

ausi commented Aug 13, 2020

This happens only with classes that have a getInstance() method, right?

I think we can fix this by using both $strClass and $strKey as cache key.

I think the correct fix would be to use static::$arrSingletons[$strClass] instead of static::$arrSingletons[$strKey] and keep using $this->arrObjects[$strKey]. So using the class name for the static cache and the instance name for storing the object in the local array.

@leofeyer leofeyer linked a pull request Aug 13, 2020 that will close this issue
leofeyer added a commit that referenced this issue Aug 13, 2020
Description
-----------

| Q                | A
| -----------------| ---
| Fixed issues     | Fixes #2152
| Docs PR or issue | -

Commits
-------

8e8ed47 Use the class name as chache key in System::import()
02fd655 Do not write to $arrStaticObjects in the import() method
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants