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

Php extension should check properties visibility #8002

Closed

Conversation

anight
Copy link
Contributor

@anight anight commented Nov 2, 2020

I think php extension should respect php visibility rules for message properties.
Please note this patch is made on top of #7993

test.proto:

syntax = "proto3";
package Test;
message Test {
        int32 foo = 1;
}

test.php:

<?php
        dl('protobuf.so');
        require_once './vendor/autoload.php';
        $t = new Test\Test();
        print_r($t->foo);
?>

Output:

$ php test.php
0

Expected output:

$ php test.php
Fatal error: Uncaught Error: Cannot access protected property Test\Test::$foo

@google-cla google-cla bot added the cla: yes label Nov 2, 2020
@haberman
Copy link
Member

haberman commented Nov 2, 2020

Thanks for this change. Is there any way to 100% prohibit any direct read/write of properties from outside of the class itself? If so I'd prefer to do that. We want the properties of the object to be totally encapsulated.

@anight
Copy link
Contributor Author

anight commented Nov 2, 2020

@haberman To my understanding the patch does exactly this. The visibility level and a class from where access is performed are checked inside zend_get_property_info():

https://github.com/php/php-src/blob/60ece88c28494945c9067448e8f9c4eeb18f8aff/Zend/zend_object_handlers.c#L376

Are you talking about some specific case I have overlooked?

@haberman
Copy link
Member

haberman commented Nov 3, 2020

Yes, your change seems to have the desired behavior. I was wondering if we could deny access without having to look up the property info. Since we want to protect all properties, it seems unfortunate to do a lookup for it.

Perhaps we could use zend_get_executed_scope() to determine whether we are being called from generated code without having to look up the property?

@anight
Copy link
Contributor Author

anight commented Nov 3, 2020

Yes, your change seems to have the desired behavior. I was wondering if we could deny access without having to look up the property info. Since we want to protect all properties, it seems unfortunate to do a lookup for it.

It seems to me that in php a parent class should always check if visibility was re-declared in the child class. I realise this may be a way too pedantic approach for protobuf case since php code generator should generate "protected" visibility for all properties. I just explained how I came to idea of my patch.

Yeah, I can re-implement zend_get_property_info() to adapt it to protobuf case, if you think this is a right approach.

@haberman
Copy link
Member

haberman commented Nov 3, 2020

Yeah, I can re-implement zend_get_property_info() to adapt it to protobuf case, if you think this is a right approach.

I am hoping this could be as simple as:

  if (zend_get_executed_scope() != intern->std.ce) {
    return EG(
    zend_throw_exception_ex(NULL, 0,
        "Protobuf fields may only be accessed through generated getters/setters.");
    return
  }

I guess we could return EG(&uninitialized_zval) if that also causes an error to be thrown. But will that throw an error in then unset() case?

@deannagarcia
Copy link
Member

I'm going to close this request given no response to the last review comment, but feel free to reopen if you'd like!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants