Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions src/Optimizely/Utils/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,52 @@ public static function areAttributesValid($attributes)
return count(array_filter(array_keys($attributes), 'is_string')) > 0;
}

/**
* @param $value The value to validate.
*
* @return boolean Representing whether attribute's value is
* a number and not NAN, INF, -INF or greater than absolute limit of 2^53.
*/
public static function isFiniteNumber($value)
{
if (!(is_int($value) || is_float($value))) {
return false;
}

if (is_nan($value) || is_infinite($value)) {
return false;
}

if (abs($value) > pow(2, 53)) {
return false;
}

return true;
}

/**
* @param $attributeKey The key to validate.
* @param $attributeValue The value to validate.
*
* @return boolean Representing whether attribute's key and value are
* valid for event payload or not.
* valid for event payload or not. Valid attribute key must be a string.
* Valid attribute value can be a string, bool, or a finite number.
*/
public static function isAttributeValid($attributeKey, $attributeValue)
{
$validTypes = array('boolean', 'double', 'integer', 'string');
return is_string($attributeKey) && in_array(gettype($attributeValue), $validTypes);
if (!is_string($attributeKey)) {
return false;
}

if (is_string($attributeValue) || is_bool($attributeValue)) {
return true;
}

if (is_int($attributeValue) || is_float($attributeValue)) {
return Validator::isFiniteNumber($attributeValue);
}

return false;
}

/**
Expand Down
28 changes: 28 additions & 0 deletions tests/UtilsTests/ValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,34 @@ public function testisAttributeValidAttributeWithInValidKeyValue()
$this->assertFalse(Validator::isAttributeValid(5.5, 'value'));
}

public function testIsFiniteNumberWithInvalidValues()
{
$this->assertFalse(Validator::IsFiniteNumber('HelloWorld'));
$this->assertFalse(Validator::IsFiniteNumber(true));
$this->assertFalse(Validator::IsFiniteNumber(false));
$this->assertFalse(Validator::IsFiniteNumber(null));
$this->assertFalse(Validator::IsFiniteNumber((object)[]));
$this->assertFalse(Validator::IsFiniteNumber([]));
$this->assertFalse(Validator::IsFiniteNumber(INF));
$this->assertFalse(Validator::IsFiniteNumber(-INF));
$this->assertFalse(Validator::IsFiniteNumber(NAN));
$this->assertFalse(Validator::IsFiniteNumber(pow(2,53) + 1));
$this->assertFalse(Validator::IsFiniteNumber(-pow(2,53) - 1));
$this->assertFalse(Validator::IsFiniteNumber(pow(2,53) + 2.0));
$this->assertFalse(Validator::IsFiniteNumber(-pow(2,53) - 2.0));
}

public function testIsFiniteNumberWithValidValues()
{
$this->assertTrue(Validator::IsFiniteNumber(0));
$this->assertTrue(Validator::IsFiniteNumber(5));
$this->assertTrue(Validator::IsFiniteNumber(5.5));
// float pow(2,53) + 1.0 evaluates to float pow(2,53)
$this->assertTrue(Validator::IsFiniteNumber(pow(2,53) + 1.0));
$this->assertTrue(Validator::IsFiniteNumber(-pow(2,53) - 1.0));
$this->assertTrue(Validator::IsFiniteNumber(pow(2,53)));
}

public function testAreEventTagsValidValidEventTags()
{
// Empty attributes
Expand Down