Re: Re: Problems with the fix for the BC break introduced in 5.4.29 and 5.5.13
| From: | Ferenc Kovacs | Date: | Mon, 30 Jun 2014 16:10:52 +0000 |
| Subject: | Re: Re: Problems with the fix for the BC break introduced in 5.4.29 and 5.5.13 | ||
| References: | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-75145@lists.php.net to get a copy of this message | ||
On Mon, Jun 30, 2014 at 5:55 PM, Julien Pauli <jpauli@php.net> wrote:
> On Mon, Jun 30, 2014 at 11:43 AM, Ferenc Kovacs <tyra3l@gmail.com> wrote:
> >
> > 2014.06.30. 9:10, "Stas Malyshev" <smalyshev@sugarcrm.com> ezt írta:
> >
> >
> >>
> >> Hi!
> >>
> >> > Can anybody suggest a workaround for this problem?
> >> > Should
> >> >
ReflectionClass#newInstanceWithoutConstructor() be enabled
> for
> >> > those classes?
> >> > If so, in 5.4/5.5?
> >>
> >> I think we should move away from the practice of using serializer for
> >> something it was never made for, namely a weird way of instantiating
> >> classes. Serializer should be working only with serialized data.
> >>
> >> Now, the question is can we instantiate the internal class without
> >> calling its ctor, and the answer here would probably be "no", at least
> >> not safely. While in the case of user class the engine can be reasonable
> >> sure even if you don't call the ctor the basic structures are
> >> initialized properly, in the case of the internal class all bets are
> >> off. I'm not sure yet which use cases require ctor not to be called, but
> >> I'm not sure how we can deliver on internal classes here.
> >>
> >> > An additional problem is when a userland class extends an internal
> class
> >> > AND implements the Serializable interface on its
> >> > own.
> >> > In such cases, knowing the serialization format is impossible for us,
> >> > and
> >> > ReflectionClass#newInstanceWithoutConstructor() still cannot be
> >> > used.
> >>
> >> Again, I would like to strongly suggest not using serialization format
> >> for hacks. It's just not what it's for, and we already suffering the
> >> consequences. We need some other solution here. Let's start with this:
> >> what gives us the guarantee that internal class which is extended by
> >> userland class will be found in proper state without calling the ctor?
> >
> > currently nothing.
> > we could
> > 1, make sure that every internal class is fine without the constructor
> (lazy
> > initiation for example). this would be probably the most work.
> > 2, we could make it mandatory or allow internal classes to opt-in to
> > mandatory that the base constructor is always called.
> > 3, we could turn the mandatory contructors final.
> >
> > 1, would allow us to keep instantiating the internal classes without
> > constructors, but it would be error prune imo.
> > 2/3 would could defend against the segfaults/etc but would be a pita to
> the
> > userland.
> >
> > I think that the mid/long range solution should be to provide a way to
> > dynamically create objects which doesn't inherit code from the original
> > class/interface but the signature should be compatible
> > (Sebastian opened a separate thread about using anonymous classes for
> > this.), but I don't think we have time for that in 5.6.
> > But we should provide an upgrade path, so the current status in 5.6 is a
> > no-go imo.
>
> I agree that the problem seem to have no solution.
>
> An object has a constructor => you can't have an object without
> calling its constructor.
>
currently it is allowed to extend the class and override the __construct()
to not call the parents.
> Passing the theoretical concepts, Stas just proved that the practical
> are just right : we can't assume internal class will work without
> calling their constructor as they usually initialize internal
> structures and states.
>
more than that, Internal classes can initialize and depend on properties
that you can't reproduce from an userland method (without calling the
original __construct()).
>
> Lazy init also is not a viable option , we can't put INIT_CHECK()
> macros everywhere.
>
and some of those macros would do what __construct() would do anyways, so
if you are instantiating without a constructor so that there is no code
execution, you wouldn't want lazy init also.
>
> Perhaps anonymous classes ?
>
yeah, that is one of the proposed solution.
> Or just to know , why can't you create a class that extends the one
> you want, and write an empty constructor into it ?
>
some mocking frameworks uses that concept for instanitating objects:
http://news.php.net/php.internals/75125
> That way you'd be able to create an object using "new" , and redefine
> the methods you want to make them return what you want. am I wrong ?
>
>
but this will still produce incomplete/unstable objects which are exposed
to the dos/security problems.
so I think that supporting the creation of mocks/doubles natively(through
Reflection)
I think it would make sense to create a wiki page (rfc maybe) and summarize
the topic, because I got the feeling that there are some ideas/suggestions
which are brought up multiple times as if they were not mentioned before. I
will try to write this up today or tomorrow and then send a mail about it
so you guys can review and extend on it.
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu