Skip to content

Commit d1514c5

Browse files
authored
(5.0) fix date parsing to disallow invalid types and formats (#99)
* fix date parsing to disallow invalid types and formats * lint
1 parent 7ca3e4b commit d1514c5

File tree

2 files changed

+21
-11
lines changed

2 files changed

+21
-11
lines changed

src/LaunchDarkly/Impl/Model/Operators.php

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace LaunchDarkly\Impl\Model;
44

55
use DateTime;
6-
use DateTimeZone;
6+
use DateTimeInterface;
77
use Exception;
88
use LaunchDarkly\Impl\SemanticVersion;
99
use LaunchDarkly\Impl\Util;
@@ -149,22 +149,26 @@ public static function is_numeric($value): bool
149149
*/
150150
public static function parseTime($in)
151151
{
152-
if (is_numeric($in)) {
152+
if (is_string($in)) {
153+
$dateTime = DateTime::createFromFormat(DateTimeInterface::RFC3339_EXTENDED, $in);
154+
if ($dateTime == null) {
155+
// try the same format but without fractional seconds
156+
$dateTime = DateTime::createFromFormat(DateTimeInterface::RFC3339, $in);
157+
}
158+
if ($dateTime == null) {
159+
return null;
160+
}
161+
return Util::dateTimeToUnixMillis($dateTime);
162+
}
163+
164+
if (is_numeric($in)) { // check this after is_string, because a numeric string would return true
153165
return $in;
154166
}
155167

156168
if ($in instanceof DateTime) {
157169
return Util::dateTimeToUnixMillis($in);
158170
}
159171

160-
if (is_string($in)) {
161-
try {
162-
$dateTime = new DateTime($in, new DateTimeZone('UTC'));
163-
return Util::dateTimeToUnixMillis($dateTime);
164-
} catch (Exception $e) {
165-
return null;
166-
}
167-
}
168172
return null;
169173
}
170174

tests/Impl/Model/OperatorsTest.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,13 @@ public function testParseTime()
5151
$this->assertEquals(1001, Operators::parseTime("1970-01-01T00:00:01.001Z"));
5252

5353

54+
$this->assertEquals(null, Operators::parseTime(null));
55+
$this->assertEquals(null, Operators::parseTime(true));
56+
$this->assertEquals(null, Operators::parseTime(""));
57+
$this->assertEquals(null, Operators::parseTime("100"));
5458
$this->assertEquals(null, Operators::parseTime("NOT A REAL TIMESTAMP"));
59+
$this->assertEquals(null, Operators::parseTime("1970-01-01")); // RFC3339 requires both date and time
60+
$this->assertEquals(null, Operators::parseTime("00:00:01.001Z")); // ditto
5561
$this->assertEquals(null, Operators::parseTime([]));
5662
}
5763

@@ -121,7 +127,7 @@ public function comparisonOperators(): array
121127
["greaterThanOrEqual", 100, "200", false],
122128
["greaterThanOrEqual", 100, true, false],
123129
["greaterThanOrEqual", true, 100, false],
124-
["greaterThanOrEqual", true, true, false],
130+
["greaterThanOrEqual", true, true, false]
125131
];
126132
}
127133

0 commit comments

Comments
 (0)