Skip to content

Commit b42f237

Browse files
authored
Merge pull request #8670 from haberman/php-wkt-submsg
Fixed SEGV in sub-message getters for well-known types when message is unset.
2 parents 769826e + 75de6aa commit b42f237

17 files changed

+50
-28
lines changed

php/ext/google/protobuf/message.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ static void Message_get(Message *intern, const upb_fielddef *f, zval *rv) {
134134
RepeatedField_GetPhpWrapper(rv, msgval.array, TypeInfo_Get(f),
135135
&intern->arena);
136136
} else {
137+
if (upb_fielddef_issubmsg(f) && !upb_msg_has(intern->msg, f)) {
138+
ZVAL_NULL(rv);
139+
return;
140+
}
137141
upb_msgval msgval = upb_msg_get(intern->msg, f);
138142
Convert_UpbToPhp(msgval, rv, TypeInfo_Get(f), &intern->arena);
139143
}
@@ -280,7 +284,6 @@ static int Message_has_property(PROTO_VAL *obj, PROTO_STR *member,
280284
* Message_unset_property()
281285
*
282286
* Object handler for unsetting a property. Called when PHP code calls:
283-
* does any of:
284287
*
285288
* unset($message->foobar);
286289
*

php/src/Google/Protobuf/Api.php

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/src/Google/Protobuf/Enum.php

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/src/Google/Protobuf/Internal/DescriptorProto.php

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/src/Google/Protobuf/Internal/EnumDescriptorProto.php

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/src/Google/Protobuf/Internal/FieldDescriptorProto.php

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/src/Google/Protobuf/Internal/FileDescriptorProto.php

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/src/Google/Protobuf/Internal/MethodDescriptorProto.php

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/src/Google/Protobuf/Internal/OneofDescriptorProto.php

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/src/Google/Protobuf/Option.php

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/src/Google/Protobuf/Type.php

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/tests/GeneratedClassTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,8 @@ public function testMessageField()
472472
{
473473
$m = new TestMessage();
474474

475+
$this->assertNull($m->getOptionalMessage());
476+
475477
$sub_m = new Sub();
476478
$sub_m->setA(1);
477479
$m->setOptionalMessage($sub_m);

php/tests/WellKnownTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ public function testStruct()
270270

271271
$m = new Value();
272272

273+
$this->assertNull($m->getStructValue());
274+
273275
$m->setNullValue(NullValue::NULL_VALUE);
274276
$this->assertSame(NullValue::NULL_VALUE, $m->getNullValue());
275277
$this->assertSame("null_value", $m->getKind());

src/google/protobuf/compiler/php/php_generator.cc

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -648,32 +648,21 @@ void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options,
648648
std::string deprecation_trigger = (field->options().deprecated()) ? "@trigger_error('" +
649649
field->name() + " is deprecated.', E_USER_DEPRECATED);\n " : "";
650650

651+
// Emit getter.
651652
if (oneof != NULL) {
652653
printer->Print(
653654
"public function get^camel_name^()\n"
654655
"{\n"
655656
" ^deprecation_trigger^return $this->readOneof(^number^);\n"
656-
"}\n\n"
657-
"public function has^camel_name^()\n"
658-
"{\n"
659-
" ^deprecation_trigger^return $this->hasOneof(^number^);\n"
660657
"}\n\n",
661658
"camel_name", UnderscoresToCamelCase(field->name(), true),
662659
"number", IntToString(field->number()),
663660
"deprecation_trigger", deprecation_trigger);
664-
} else if (field->has_presence()) {
661+
} else if (field->has_presence() && !field->message_type()) {
665662
printer->Print(
666663
"public function get^camel_name^()\n"
667664
"{\n"
668665
" ^deprecation_trigger^return isset($this->^name^) ? $this->^name^ : ^default_value^;\n"
669-
"}\n\n"
670-
"public function has^camel_name^()\n"
671-
"{\n"
672-
" ^deprecation_trigger^return isset($this->^name^);\n"
673-
"}\n\n"
674-
"public function clear^camel_name^()\n"
675-
"{\n"
676-
" ^deprecation_trigger^unset($this->^name^);\n"
677666
"}\n\n",
678667
"camel_name", UnderscoresToCamelCase(field->name(), true),
679668
"name", field->name(),
@@ -690,6 +679,32 @@ void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options,
690679
"deprecation_trigger", deprecation_trigger);
691680
}
692681

682+
// Emit hazzers/clear.
683+
if (oneof) {
684+
printer->Print(
685+
"public function has^camel_name^()\n"
686+
"{\n"
687+
" ^deprecation_trigger^return $this->hasOneof(^number^);\n"
688+
"}\n\n",
689+
"camel_name", UnderscoresToCamelCase(field->name(), true),
690+
"number", IntToString(field->number()),
691+
"deprecation_trigger", deprecation_trigger);
692+
} else if (field->has_presence()) {
693+
printer->Print(
694+
"public function has^camel_name^()\n"
695+
"{\n"
696+
" ^deprecation_trigger^return isset($this->^name^);\n"
697+
"}\n\n"
698+
"public function clear^camel_name^()\n"
699+
"{\n"
700+
" ^deprecation_trigger^unset($this->^name^);\n"
701+
"}\n\n",
702+
"camel_name", UnderscoresToCamelCase(field->name(), true),
703+
"name", field->name(),
704+
"default_value", DefaultForField(field),
705+
"deprecation_trigger", deprecation_trigger);
706+
}
707+
693708
// For wrapper types, generate an additional getXXXUnwrapped getter
694709
if (!field->is_map() &&
695710
!field->is_repeated() &&

0 commit comments

Comments
 (0)