From 682383b24b1325990492c8769d2a98481b03e440 Mon Sep 17 00:00:00 2001
From: jano3 <jano@bob.co.za>
Date: Mon, 1 Jul 2024 07:24:00 +0200
Subject: [PATCH] Fix potential nil pointer and index out of range panics for
 audit event formatting

---
 audit/audit.go | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/audit/audit.go b/audit/audit.go
index 1fb3c2c..f6ef14c 100644
--- a/audit/audit.go
+++ b/audit/audit.go
@@ -68,8 +68,14 @@ func GetChanges(original any, new any) (map[string]any, error) {
 			// ["Account", "ID"]
 			// 0 = Object
 			// 1 = field
+			var index int64 = -1
+
+			if string_utils.IsNumericString(change.Path[1]) {
+				index, _ = number_utils.StringToInt64(change.Path[1])
+			}
+
 			objectKey := ToSnakeCase(change.Path[0])
-			didInsert := CheckToFormatForAuditEvent(changes, original, new, change.Path[0], objectKey, -1)
+			didInsert := CheckToFormatForAuditEvent(changes, original, new, change.Path[0], objectKey, int(index))
 			if didInsert {
 				continue
 			}
@@ -254,10 +260,14 @@ func CheckToFormatForAuditEvent(changes map[string]any, original any, new any, f
 		}
 
 		if doGroupSlice {
-			changes[objectKey] = FieldChange{
-				From: []string{*originalFormattedObject},
-				To:   []string{*newFormattedObject},
+			fieldChange := FieldChange{}
+			if originalFormattedObject != nil {
+				fieldChange.From = []string{*originalFormattedObject}
 			}
+			if newFormattedObject != nil {
+				fieldChange.To = []string{*newFormattedObject}
+			}
+			changes[objectKey] = fieldChange
 		} else {
 			if index > -1 {
 				objectKey = fmt.Sprintf("%s[%d]", field, index)
@@ -333,6 +343,9 @@ func checkToExecuteAuditFormatter(fieldValue reflect.Value) *string {
 
 func checkToFormatForAuditEvent(fieldValue reflect.Value, index int) *string {
 	if fieldValue.Kind() == reflect.Ptr {
+		if fieldValue.IsNil() {
+			return nil
+		}
 		fieldValue = fieldValue.Elem()
 	}
 
@@ -341,12 +354,16 @@ func checkToFormatForAuditEvent(fieldValue reflect.Value, index int) *string {
 		formattedField = checkToExecuteAuditFormatter(fieldValue)
 	} else if fieldValue.Kind() == reflect.Slice &&
 		fieldValue.Len() > 0 {
-		if index >= fieldValue.Len() {
+		if index == -1 ||
+			index > fieldValue.Len() {
 			return nil
 		}
 
 		sliceFieldValue := fieldValue.Index(index)
 		if sliceFieldValue.Kind() == reflect.Ptr {
+			if fieldValue.IsNil() {
+				return nil
+			}
 			sliceFieldValue = sliceFieldValue.Elem()
 		}
 
-- 
GitLab