Skip to content

Commit f16f39d

Browse files
authored
Don't treat numeric strings as numbers (#84)
1 parent 03e64d1 commit f16f39d

File tree

2 files changed

+72
-4
lines changed

2 files changed

+72
-4
lines changed

src/LaunchDarkly/Impl/Model/Operators.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,22 @@ public static function apply(?string $op, $u, $c): bool
6363
}
6464
break;
6565
case "lessThan":
66-
if (is_numeric($u) && is_numeric($c)) {
66+
if (self::is_numeric($u) && self::is_numeric($c)) {
6767
return $u < $c;
6868
}
6969
break;
7070
case "lessThanOrEqual":
71-
if (is_numeric($u) && is_numeric($c)) {
71+
if (self::is_numeric($u) && self::is_numeric($c)) {
7272
return $u <= $c;
7373
}
7474
break;
7575
case "greaterThan":
76-
if (is_numeric($u) && is_numeric($c)) {
76+
if (self::is_numeric($u) && self::is_numeric($c)) {
7777
return $u > $c;
7878
}
7979
break;
8080
case "greaterThanOrEqual":
81-
if (is_numeric($u) && is_numeric($c)) {
81+
if (self::is_numeric($u) && self::is_numeric($c)) {
8282
return $u >= $c;
8383
}
8484
break;
@@ -118,6 +118,21 @@ public static function apply(?string $op, $u, $c): bool
118118
return false;
119119
}
120120

121+
/**
122+
* A stricter version of the built-in is_numeric checker.
123+
*
124+
* This version will check if the provided value is numeric, but isn't a
125+
* string. This helps us stay consistent with the way flag evaluations work
126+
* in more strictly typed languages.
127+
*
128+
* @param mixed $value
129+
* @return bool
130+
*/
131+
public static function is_numeric($value): bool
132+
{
133+
return is_numeric($value) && !is_string($value);
134+
}
135+
121136
/**
122137
* @param mixed|null $in
123138
* @return ?numeric

tests/Impl/Model/OperatorsTest.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,57 @@ public function testSemVer()
7474
$this->assertFalse(Operators::apply("semVerLessThan", "2.0.0", "xbad%ver"));
7575
$this->assertFalse(Operators::apply("semVerGreaterThan", "2.0.0", "xbad%ver"));
7676
}
77+
78+
public function comparisonOperators(): array
79+
{
80+
return [
81+
["lessThan", 100, 200, true],
82+
["lessThan", 200, 100, false],
83+
["lessThan", 100, 100, false],
84+
["lessThan", "100", 200, false],
85+
["lessThan", "100", "200", false],
86+
["lessThan", 100, "200", false],
87+
["lessThan", 100, true, false],
88+
["lessThan", true, 100, false],
89+
["lessThan", true, true, false],
90+
91+
["lessThanOrEqual", 100, 200, true],
92+
["lessThanOrEqual", 200, 100, false],
93+
["lessThanOrEqual", 100, 100, true],
94+
["lessThanOrEqual", "100", 200, false],
95+
["lessThanOrEqual", "100", "200", false],
96+
["lessThanOrEqual", 100, "200", false],
97+
["lessThanOrEqual", 100, true, false],
98+
["lessThanOrEqual", true, 100, false],
99+
["lessThanOrEqual", true, true, false],
100+
101+
["greaterThan", 100, 200, false],
102+
["greaterThan", 200, 100, true],
103+
["greaterThan", 100, 100, false],
104+
["greaterThan", "100", 200, false],
105+
["greaterThan", "100", "200", false],
106+
["greaterThan", 100, "200", false],
107+
["greaterThan", 100, true, false],
108+
["greaterThan", true, 100, false],
109+
["greaterThan", true, true, false],
110+
111+
["greaterThanOrEqual", 100, 200, false],
112+
["greaterThanOrEqual", 200, 100, true],
113+
["greaterThanOrEqual", 100, 100, true],
114+
["greaterThanOrEqual", "100", 200, false],
115+
["greaterThanOrEqual", "100", "200", false],
116+
["greaterThanOrEqual", 100, "200", false],
117+
["greaterThanOrEqual", 100, true, false],
118+
["greaterThanOrEqual", true, 100, false],
119+
["greaterThanOrEqual", true, true, false],
120+
];
121+
}
122+
123+
/**
124+
* @dataProvider comparisonOperators
125+
*/
126+
public function testComparisonOperators($operator, $lhs, $rhs, $expected)
127+
{
128+
$this->assertEquals($expected, Operators::apply($operator, $lhs, $rhs));
129+
}
77130
}

0 commit comments

Comments
 (0)