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
79 changes: 68 additions & 11 deletions pkg/event/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ package event

import (
"errors"
"fmt"
"math"
"reflect"
"strings"
"time"

Expand Down Expand Up @@ -292,22 +295,76 @@ func getTagValue(eventTags map[string]interface{}) (float64, error) {
return 0, errors.New("no event tag found for value")
}

// Validates if the type of provided value is numeric.
func isNumericType(value interface{}) (float64, error) {
switch i := value.(type) {
case int:
return float64(i), nil
case int8:
return float64(i), nil
case int16:
return float64(i), nil
case int32:
return float64(i), nil
case int64:
return float64(i), nil
case uint:
return float64(i), nil
case uint8:
return float64(i), nil
case uint16:
return float64(i), nil
case uint32:
return float64(i), nil
case uint64:
return float64(i), nil
case uintptr:
return float64(i), nil
case float32:
return float64(i), nil
case float64:
return i, nil
default:
v := reflect.ValueOf(value)
v = reflect.Indirect(v)
return math.NaN(), fmt.Errorf("can't convert %v to float64", v.Type())
}
}

// Validates if the provided value is a valid numeric value.
func isValidNumericValue(value interface{}) bool {
if floatValue, err := isNumericType(value); err == nil {
if math.IsNaN(floatValue) {
return false
}
if math.IsInf(floatValue, 1) {
return false
}
if math.IsInf(floatValue, -1) {
return false
}
if math.IsInf(floatValue, 0) {
return false
}
if math.Abs(floatValue) > math.Pow(2, 53) {
return false
}
return true
}
return false
}

// check if attribute value is valid
func isValidAttribute(value interface{}) bool {
if value == nil {
return false
}
if _, ok := value.(string); ok {
return true
}
if _, ok := value.(float64); ok {
return true
}
if _, ok := value.(int); ok {
return true
}
if _, ok := value.(bool); ok {

switch value.(type) {
// https://go.dev/tour/basics/11
case bool, string:
return true
default:
return isValidNumericValue(value)
}
return false
}
37 changes: 33 additions & 4 deletions pkg/event/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package event

import (
"context"
"math"
"math/rand"
"testing"
"time"
Expand Down Expand Up @@ -241,8 +242,36 @@ func TestIsValidAttribute(t *testing.T) {
assert.False(t, isValidAttribute([]string{}))
assert.False(t, isValidAttribute([]interface{}{}))
assert.False(t, isValidAttribute(make(chan int)))
assert.True(t, isValidAttribute("123"))
assert.True(t, isValidAttribute(1.11))
assert.True(t, isValidAttribute(1))
assert.True(t, isValidAttribute(true))
assert.False(t, isValidAttribute(complex64(1234.1231)))
assert.False(t, isValidAttribute(complex128(123446.123123)))
assert.False(t, isValidAttribute(math.Pow(2, 54)))

assert.False(t, isValidAttribute(math.NaN()))
posInf := math.Inf(1)
assert.False(t, isValidAttribute(posInf))
posInf += 12.2 // infinite value will still propagate after add operation
assert.False(t, isValidAttribute(posInf))
negInf := math.Inf(-1)
assert.False(t, isValidAttribute(negInf))
negInf /= negInf // will turn infinite into NaN
assert.False(t, isValidAttribute(negInf))
assert.False(t, isValidAttribute(math.Inf(0)))

assert.True(t, isValidAttribute(bool(true)))
assert.True(t, isValidAttribute(string("abcd")))
assert.True(t, isValidAttribute(int(1)))
assert.True(t, isValidAttribute(int8(-12)))
assert.True(t, isValidAttribute(int16(-123)))
assert.True(t, isValidAttribute(int32(1234)))
assert.True(t, isValidAttribute(int64(123446)))
assert.True(t, isValidAttribute(uint(1)))
assert.True(t, isValidAttribute(uint8(12)))
assert.True(t, isValidAttribute(uint16(123)))
assert.True(t, isValidAttribute(uint32(1234)))
assert.True(t, isValidAttribute(uint64(123446)))
assert.True(t, isValidAttribute(uintptr(1)))
assert.True(t, isValidAttribute(float32(12.11)))
assert.True(t, isValidAttribute(float64(123.1231)))
assert.True(t, isValidAttribute(byte(134)))
assert.True(t, isValidAttribute(rune(123446)))
}