Skip to content

Commit

Permalink
Merge pull request #32 from pquerna/pq/enum_values
Browse files Browse the repository at this point in the history
use the OCSF value for enums, rather than an offset
  • Loading branch information
valllabh authored May 27, 2024
2 parents d54e2da + ed29478 commit 96609ad
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 80 deletions.
34 changes: 10 additions & 24 deletions ocsf/mappers/protobuff_v3/enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ func (e *Enum) GetValue(name string) (*EnumValue, bool) {
// Get enum values sorted by name (with UNKNOWN coming first)
func (e *Enum) GetValues() []*EnumValue {

// Add UNKNOWN if not present
if !e.HasUnknown() {
// Add UNSPECIFIED if not present
if !e.HasUNSPECIFIED() {
e.AddValue(&EnumValue{
Name: "UNKNOWN",
Name: "UNSPECIFIED",
Value: 0,
Comment: Comment{
"Type": "NON_OCSF_VALUE",
},
Expand All @@ -41,7 +42,7 @@ func (e *Enum) GetValues() []*EnumValue {

// Sort values by name (with UNKNOWN coming first)
sort.Slice(values, func(i, j int) bool {
return valueSorter(values, i, j)
return values[i].Value < values[j].Value
})

return values
Expand All @@ -59,8 +60,8 @@ func (e *Enum) Marshal() string {
values := e.GetValues()

// Marshal values and add to content
for i, v := range values {
content = append(content, "\t"+v.Marshal(i))
for _, v := range values {
content = append(content, "\t"+v.Marshal())
}

// Close Enum
Expand All @@ -85,31 +86,16 @@ func (e *Enum) GetPackage() string {
return e.Package.GetFullName()
}

// Enum has at least one value ending with UNKNOWN
func (e *Enum) HasUnknown() bool {
// Enum has at least one value ending with HasUNSPECIFIED
func (e *Enum) HasUNSPECIFIED() bool {
for _, v := range e.values {
if strings.HasSuffix(strings.ToUpper(v.Name), "UNKNOWN") {
if v.Value == 0 {
return true
}
}
return false
}

// Sorts EnumValues by name, with "UNKNOWN" coming first
func valueSorter(values []*EnumValue, i int, j int) bool {

// if string ends with UNKNOWN, it should be first
if strings.HasSuffix(strings.ToUpper(values[i].Name), "UNKNOWN") {
return true
}

if strings.HasSuffix(strings.ToUpper(values[j].Name), "UNKNOWN") {
return false
}

return values[i].Name < values[j].Name
}

// ToEnumName converts a string to a valid Enum Name
func ToEnumName(input string) string {

Expand Down
12 changes: 8 additions & 4 deletions ocsf/mappers/protobuff_v3/enumValue.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ import (
"github.com/iancoleman/strcase"
)

func (ev *EnumValue) Marshal(index int) string {
func (ev *EnumValue) Marshal() string {
content := []string{}

content = append(content, ToEnumValueName(ev.enum.Name+" "+ev.Name))
// NOTE: some OCSF Values have non-Zero UNKNOKWN values, while protos want a zero value unknown.
// <code>class_uid * 100 + activity_id</code>. -> These are OCSF values, and we still emit a UNSPECIFRIED=0 enum
// value
baseName := ev.enum.Name + " " + ev.Name
content = append(content, ToEnumValueName(baseName))

content = append(content, fmt.Sprintf("= %d;", index))
content = append(content, fmt.Sprintf("= %d;", ev.Value))

if len(ev.Comment) > 0 {
content = append(content, "//")
Expand All @@ -30,7 +34,7 @@ func ToEnumValueName(input string) string {
value, exists := GetMapper().Cache.EnumValues.Get(input)

if exists {
return fmt.Sprint(value)
return value.(string)
}

output := input
Expand Down
58 changes: 7 additions & 51 deletions ocsf/mappers/protobuff_v3/enum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,67 +7,23 @@ import (

func TestValueSorter(t *testing.T) {
values := []*EnumValue{
{Name: "UNKNOWN"},
{Name: "B"},
{Name: "A"},
{Name: "C"},
{Name: "D"},
{Name: "E"},
{Name: "F"},
{Name: "G"},
{Name: "H"},
{Name: "I"},
{Name: "J"},
{Name: "K"},
{Name: "L"},
{Name: "M"},
{Name: "N"},
{Name: "O"},
{Name: "P"},
{Name: "Q"},
{Name: "R"},
{Name: "S"},
{Name: "T"},
{Name: "U"},
{Name: "V"},
{Name: "W"},
{Name: "X"},
{Name: "Y"},
{Name: "Z"},
{Name: "UNSPECIFIED", Value: 0},
{Name: "B", Value: 2},
{Name: "A", Value: 1},
{Name: "C", Value: 3},
{Name: "D", Value: 4},
}

sort.Slice(values, func(i, j int) bool {
return valueSorter(values, i, j)
return values[i].Value < values[j].Value
})

expected := []string{
"UNKNOWN",
"UNSPECIFIED",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
}

for i, v := range values {
Expand Down
10 changes: 9 additions & 1 deletion ocsf/mappers/protobuff_v3/mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,15 @@ func (mapper *mapper) populateFieldsFromAttributes(message *Message, attributes
field.Type = FIELD_TYPE_OBJECT
}

if len(attr.Enum) > 0 {
if len(attr.Enum) > 0 && attr.Type == "string_t" {
// there are a couple string_t enums that should just be represented as strings
field.Type = FIELD_TYPE_PRIMITIVE
validKeys := make([]string, 0, len(attr.Enum))
for aek := range attr.Enum {
validKeys = append(validKeys, aek)
}
field.Comment["AllowedValues"] = strings.Join(validKeys, ", ")
} else if len(attr.Enum) > 0 {
field.Type = FIELD_TYPE_ENUM
}

Expand Down

0 comments on commit 96609ad

Please sign in to comment.