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.
pull/6277/head
Leonard Hecker 6 years ago committed by Paul Yang
parent f2a919f58f
commit 43307d4da0
  1. 4
      conformance/failure_list_php.txt
  2. 9
      php/src/Google/Protobuf/Internal/EnumDescriptor.php
  3. 24
      php/src/Google/Protobuf/Internal/GPBUtil.php

@ -3,10 +3,6 @@ Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
Recommended.FieldMaskTooManyUnderscore.JsonOutput Recommended.FieldMaskTooManyUnderscore.JsonOutput
Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput
Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput 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 Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
Required.Proto3.JsonInput.FloatFieldTooLarge Required.Proto3.JsonInput.FloatFieldTooLarge
Required.Proto3.JsonInput.FloatFieldTooSmall Required.Proto3.JsonInput.FloatFieldTooSmall

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

@ -504,17 +504,29 @@ class GPBUtil
public static function formatDuration($value) public static function formatDuration($value)
{ {
if (bccomp($value->getSeconds(), "315576000001") != -1) { if (bccomp($value->getSeconds(), '315576000001') != -1) {
throw new GPBDecodeException("Duration number too large."); throw new GPBDecodeException('Duration number too large.');
} }
if (bccomp($value->getSeconds(), "-315576000001") != 1) { if (bccomp($value->getSeconds(), '-315576000001') != 1) {
throw new GPBDecodeException("Duration number too small."); 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) public static function parseFieldMask($paths_string)
{ {

Loading…
Cancel
Save