Skip to content

Commit 6fd69af

Browse files
committed
PHPC-790: UTCDateTime constructor should truncate floats
1 parent 8d7e358 commit 6fd69af

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

src/BSON/UTCDateTime.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
/* External libs */
2828
#include <bson.h>
2929
#include <mongoc.h>
30+
#include <math.h>
3031

3132
/* PHP Core stuff */
3233
#include <php.h>
@@ -157,7 +158,7 @@ static bool php_phongo_utcdatetime_init_from_date(php_phongo_utcdatetime_t *inte
157158
return true;
158159
}
159160

160-
/* {{{ proto void UTCDateTime::__construct([int|string|DateTimeInterface $milliseconds = null])
161+
/* {{{ proto void UTCDateTime::__construct([int|float|string|DateTimeInterface $milliseconds = null])
161162
Construct a new BSON UTCDateTime type from either the current time,
162163
milliseconds since the epoch, or a DateTimeInterface object. Defaults to the
163164
current time. */
@@ -199,6 +200,16 @@ PHP_METHOD(UTCDateTime, __construct)
199200
return;
200201
}
201202

203+
if (Z_TYPE_P(milliseconds) == IS_DOUBLE) {
204+
char tmp[24];
205+
int tmp_len;
206+
207+
tmp_len = snprintf(tmp, sizeof(tmp), "%.0f", Z_DVAL_P(milliseconds) > 0 ? floor(Z_DVAL_P(milliseconds)) : ceil(Z_DVAL_P(milliseconds)));
208+
209+
php_phongo_utcdatetime_init_from_string(intern, tmp, tmp_len TSRMLS_CC);
210+
return;
211+
}
212+
202213
if (Z_TYPE_P(milliseconds) != IS_STRING) {
203214
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected integer or string, %s given", zend_get_type_by_const(Z_TYPE_P(milliseconds)));
204215
return;

tests/bson/bson-utcdatetime-007.phpt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
MongoDB\BSON\UTCDateTime constructor truncates floating point values
3+
--FILE--
4+
<?php
5+
6+
$tests = [
7+
new MongoDB\BSON\UTCDateTime(1416445411987.0),
8+
new MongoDB\BSON\UTCDateTime(2147483647.0),
9+
new MongoDB\BSON\UTCDateTime(1234.5678),
10+
];
11+
12+
foreach ($tests as $test) {
13+
var_dump($test);
14+
}
15+
16+
?>
17+
===DONE===
18+
<?php exit(0); ?>
19+
--EXPECTF--
20+
object(MongoDB\BSON\UTCDateTime)#%d (%d) {
21+
["milliseconds"]=>
22+
string(13) "1416445411987"
23+
}
24+
object(MongoDB\BSON\UTCDateTime)#%d (%d) {
25+
["milliseconds"]=>
26+
string(10) "2147483647"
27+
}
28+
object(MongoDB\BSON\UTCDateTime)#%d (%d) {
29+
["milliseconds"]=>
30+
string(4) "1234"
31+
}
32+
===DONE===

tests/bson/bson-utcdatetime_error-004.phpt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ MongoDB\BSON\UTCDateTime constructor requires integer or string argument
55

66
require_once __DIR__ . '/../utils/tools.php';
77

8+
/* UTCDateTime::__construct() internally converts floats to integers, so we will
9+
* not use a float to test for an invalid value. We also don't test an object,
10+
* since that is used for validating a possible DateTimeInterface argument. */
811
$invalidValues = [true, []];
912

1013
foreach ($invalidValues as $invalidValue) {

0 commit comments

Comments
 (0)