php: Fix formatting of Duration (#6155)

* php: Fixed php notices for unknown enum indices

* php: Fixed formatting of Duration

This fixes:
* Missing nanoseconds. The nanoseconds where divided as a float and
  implicitly converted to a string before being passed to bcadd.
  This can result in a float formatted in scientific/exponential notation,
  which bcmath doesn't understand.
* Durations are supposed to be formatted without trailing zeroes.
This commit is contained in:
Leonard Hecker 2019-06-18 19:31:50 +02:00 committed by Paul Yang
parent f2a919f58f
commit 43307d4da0
3 changed files with 32 additions and 15 deletions

View File

@ -3,10 +3,6 @@ Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
Recommended.FieldMaskTooManyUnderscore.JsonOutput
Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput
Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput
Recommended.Proto3.JsonInput.DurationHas3FractionalDigits.Validator
Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator
Recommended.Proto3.JsonInput.DurationHas9FractionalDigits.Validator
Recommended.Proto3.JsonInput.DurationHasZeroFractionalDigit.Validator
Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
Required.Proto3.JsonInput.FloatFieldTooLarge
Required.Proto3.JsonInput.FloatFieldTooSmall

View File

@ -39,17 +39,26 @@ class EnumDescriptor
public function getValueByNumber($number)
{
return $this->value[$number];
if (isset($this->value[$number])) {
return $this->value[$number];
}
return null;
}
public function getValueByName($name)
{
return $this->name_to_value[$name];
if (isset($this->name_to_value[$name])) {
return $this->name_to_value[$name];
}
return null;
}
public function getValueDescriptorByIndex($index)
{
return $this->value_descriptor[$index];
if (isset($this->value_descriptor[$index])) {
return $this->value_descriptor[$index];
}
return null;
}
public function getValueCount()

View File

@ -504,18 +504,30 @@ class GPBUtil
public static function formatDuration($value)
{
if (bccomp($value->getSeconds(), "315576000001") != -1) {
throw new GPBDecodeException("Duration number too large.");
if (bccomp($value->getSeconds(), '315576000001') != -1) {
throw new GPBDecodeException('Duration number too large.');
}
if (bccomp($value->getSeconds(), "-315576000001") != 1) {
throw new GPBDecodeException("Duration number too small.");
if (bccomp($value->getSeconds(), '-315576000001') != 1) {
throw new GPBDecodeException('Duration number too small.');
}
return strval(bcadd($value->getSeconds(),
$value->getNanos() / 1000000000.0, 9));
$nanos = $value->getNanos();
if ($nanos === 0) {
return (string) $value->getSeconds();
}
if ($nanos % 1000000 === 0) {
$digits = 3;
} elseif ($nanos % 1000 === 0) {
$digits = 6;
} else {
$digits = 9;
}
$nanos = bcdiv($nanos, '1000000000', $digits);
return bcadd($value->getSeconds(), $nanos, $digits);
}
public static function parseFieldMask($paths_string)
{
$field_mask = new FieldMask();