Skip to content

Commit 24e43d9

Browse files
authored
refactor: misc (#110)
1 parent c26efc5 commit 24e43d9

File tree

7 files changed

+55
-72
lines changed

7 files changed

+55
-72
lines changed

decoder.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,18 @@ func decodeErrors(obj *bindings.WafObject) (map[string][]string, error) {
3838
return wafErrors, nil
3939
}
4040

41-
func decodeDiagnostics(obj *bindings.WafObject) (*Diagnostics, error) {
41+
func decodeDiagnostics(obj *bindings.WafObject) (Diagnostics, error) {
4242
if !obj.IsMap() {
43-
return nil, errors.ErrInvalidObjectType
43+
return Diagnostics{}, errors.ErrInvalidObjectType
4444
}
4545
if obj.Value == 0 && obj.NbEntries > 0 {
46-
return nil, errors.ErrNilObjectPtr
46+
return Diagnostics{}, errors.ErrNilObjectPtr
4747
}
4848

49-
var diags Diagnostics
50-
var err error
49+
var (
50+
diags Diagnostics
51+
err error
52+
)
5153
for i := uint64(0); i < obj.NbEntries; i++ {
5254
objElem := unsafe.CastWithOffset[bindings.WafObject](obj.Value, i)
5355
key := unsafe.GostringSized(unsafe.Cast[byte](objElem.ParameterName), objElem.ParameterNameLength)
@@ -62,6 +64,8 @@ func decodeDiagnostics(obj *bindings.WafObject) (*Diagnostics, error) {
6264
diags.Rules, err = decodeDiagnosticsEntry(objElem)
6365
case "rules_data":
6466
diags.RulesData, err = decodeDiagnosticsEntry(objElem)
67+
case "exclusion_data":
68+
diags.RulesData, err = decodeDiagnosticsEntry(objElem)
6569
case "rules_override":
6670
diags.RulesOverrides, err = decodeDiagnosticsEntry(objElem)
6771
case "processors":
@@ -74,11 +78,11 @@ func decodeDiagnostics(obj *bindings.WafObject) (*Diagnostics, error) {
7478
// ignore?
7579
}
7680
if err != nil {
77-
return nil, err
81+
return Diagnostics{}, err
7882
}
7983
}
8084

81-
return &diags, nil
85+
return diags, nil
8286
}
8387

8488
func decodeDiagnosticsEntry(obj *bindings.WafObject) (*DiagnosticEntry, error) {

errors/waf.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,23 @@ const (
3333
ErrEmptyRuleAddresses
3434
)
3535

36+
var errorStrMap = map[RunError]string{
37+
ErrInternal: "internal waf error",
38+
ErrInvalidObject: "invalid waf object",
39+
ErrInvalidArgument: "invalid waf argument",
40+
ErrTimeout: "waf timeout",
41+
ErrOutOfMemory: "out of memory",
42+
ErrEmptyRuleAddresses: "empty rule addresses",
43+
}
44+
3645
// Error returns the string representation of the RunError.
3746
func (e RunError) Error() string {
38-
switch e {
39-
case ErrInternal:
40-
return "internal waf error"
41-
case ErrTimeout:
42-
return "waf timeout"
43-
case ErrInvalidObject:
44-
return "invalid waf object"
45-
case ErrInvalidArgument:
46-
return "invalid waf argument"
47-
case ErrOutOfMemory:
48-
return "out of memory"
49-
case ErrEmptyRuleAddresses:
50-
return "empty rule addresses"
51-
default:
47+
description, ok := errorStrMap[e]
48+
if !ok {
5249
return fmt.Sprintf("unknown waf error %d", e)
5350
}
51+
52+
return description
5453
}
5554

5655
// PanicError is an error type wrapping a recovered panic value that happened

handle.go

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -66,39 +66,35 @@ func NewHandle(rules any, keyObfuscatorRegex string, valueObfuscatorRegex string
6666
diagnosticsWafObj := new(bindings.WafObject)
6767
defer wafLib.WafObjectFree(diagnosticsWafObj)
6868

69-
cHandle := wafLib.WafInit(obj, config, diagnosticsWafObj)
70-
// Upon failure, the WAF may have produced some diagnostics to help signal what went wrong...
71-
var (
72-
diags = new(Diagnostics)
73-
diagsErr error
74-
)
75-
if !diagnosticsWafObj.IsInvalid() {
76-
diags, diagsErr = decodeDiagnostics(diagnosticsWafObj)
69+
unsafe.KeepAlive(encoder.cgoRefs)
70+
71+
return newHandle(wafLib.WafInit(obj, config, diagnosticsWafObj), diagnosticsWafObj)
72+
}
73+
74+
// newHandle creates a new Handle from a C handle (nullable) and a diagnostics object.
75+
// and it handles the multiple ways a WAF initialization can fail.
76+
func newHandle(cHandle bindings.WafHandle, diagnosticsWafObj *bindings.WafObject) (*Handle, error) {
77+
diags, diagsErr := decodeDiagnostics(diagnosticsWafObj)
78+
if cHandle == 0 && diagsErr != nil { // WAF Failed initialization and we manage to decode the diagnostics, return the diagnostics error
79+
if err := diags.TopLevelError(); err != nil {
80+
return nil, fmt.Errorf("could not instantiate the WAF: %w", err)
81+
}
7782
}
7883

7984
if cHandle == 0 {
8085
// WAF Failed initialization, report the best possible error...
81-
if diags != nil && diagsErr == nil {
82-
// We were able to parse out some diagnostics from the WAF!
83-
err = diags.TopLevelError()
84-
if err != nil {
85-
return nil, fmt.Errorf("could not instantiate the WAF: %w", err)
86-
}
87-
}
8886
return nil, errors.New("could not instantiate the WAF")
8987
}
9088

91-
// The WAF successfully initialized at this stage...
89+
// The WAF successfully initialized at this stage but if the diagnostics decoding failed, we still need to cleanup
9290
if diagsErr != nil {
9391
wafLib.WafDestroy(cHandle)
9492
return nil, fmt.Errorf("could not decode the WAF diagnostics: %w", diagsErr)
9593
}
9694

97-
unsafe.KeepAlive(encoder.cgoRefs)
98-
9995
handle := &Handle{
10096
cHandle: cHandle,
101-
diagnostics: *diags,
97+
diagnostics: diags,
10298
}
10399

104100
handle.refCounter.Store(1) // We count the handle itself in the counter
@@ -170,25 +166,9 @@ func (handle *Handle) Update(newRules any) (*Handle, error) {
170166
}
171167

172168
diagnosticsWafObj := new(bindings.WafObject)
173-
174-
cHandle := wafLib.WafUpdate(handle.cHandle, obj, diagnosticsWafObj)
175-
unsafe.KeepAlive(encoder.cgoRefs)
176-
if cHandle == 0 {
177-
return nil, errors.New("could not update the WAF instance")
178-
}
179-
180169
defer wafLib.WafObjectFree(diagnosticsWafObj)
181170

182-
if err != nil { // Something is very wrong
183-
return nil, fmt.Errorf("could not decode the WAF ruleset errors: %w", err)
184-
}
185-
186-
newHandle := &Handle{
187-
cHandle: cHandle,
188-
}
189-
190-
newHandle.refCounter.Store(1) // We count the handle itself in the counter
191-
return newHandle, nil
171+
return newHandle(wafLib.WafUpdate(handle.cHandle, obj, diagnosticsWafObj), diagnosticsWafObj)
192172
}
193173

194174
// Close puts the handle in termination state, when all the contexts are closed the handle will be destroyed

internal/bindings/safe.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
"github.com/pkg/errors"
1616
)
1717

18-
func newPanicError(in func() error, err error) *wafErrors.PanicError {
18+
func newPanicError(in any, err error) *wafErrors.PanicError {
1919
return &wafErrors.PanicError{
2020
In: runtime.FuncForPC(reflect.ValueOf(in).Pointer()).Name(),
2121
Err: err,
@@ -24,7 +24,7 @@ func newPanicError(in func() error, err error) *wafErrors.PanicError {
2424

2525
// tryCall calls function `f` and recovers from any panic occurring while it
2626
// executes, returning it in a `PanicError` object type.
27-
func tryCall(f func() error) (err error) {
27+
func tryCall[T any](f func() T) (res T, err error) {
2828
defer func() {
2929
r := recover()
3030
if r == nil {
@@ -43,5 +43,6 @@ func tryCall(f func() error) (err error) {
4343

4444
err = newPanicError(f, err)
4545
}()
46-
return f()
46+
res = f()
47+
return
4748
}

internal/bindings/safe_test.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ package bindings
77

88
import (
99
"errors"
10-
wafErrors "github.com/DataDog/go-libddwaf/v3/errors"
1110
"strconv"
1211
"testing"
1312

13+
wafErrors "github.com/DataDog/go-libddwaf/v3/errors"
14+
1415
"github.com/stretchr/testify/require"
1516
)
1617

@@ -21,7 +22,7 @@ func TestTryCall(t *testing.T) {
2122
t.Run("panic", func(t *testing.T) {
2223
t.Run("error", func(t *testing.T) {
2324
// panic called with an error
24-
err := tryCall(func() error {
25+
_, err := tryCall(func() error {
2526
panic(myPanicErr)
2627
})
2728
require.Error(t, err)
@@ -33,7 +34,7 @@ func TestTryCall(t *testing.T) {
3334
t.Run("string", func(t *testing.T) {
3435
// panic called with a string
3536
str := "woops"
36-
err := tryCall(func() error {
37+
_, err := tryCall(func() error {
3738
panic(str)
3839
})
3940
require.Error(t, err)
@@ -45,7 +46,7 @@ func TestTryCall(t *testing.T) {
4546
t.Run("int", func(t *testing.T) {
4647
// panic called with an int to cover the default fallback in tryCall
4748
var i int64 = 42
48-
err := tryCall(func() error {
49+
_, err := tryCall(func() error {
4950
panic(i)
5051
})
5152
require.Error(t, err)
@@ -56,14 +57,14 @@ func TestTryCall(t *testing.T) {
5657
})
5758

5859
t.Run("error", func(t *testing.T) {
59-
err := tryCall(func() error {
60+
err, _ := tryCall(func() error {
6061
return myErr
6162
})
6263
require.Equal(t, myErr, err)
6364
})
6465

6566
t.Run("no error", func(t *testing.T) {
66-
err := tryCall(func() error {
67+
err, _ := tryCall(func() error {
6768
return nil
6869
})
6970
require.NoError(t, err)

internal/bindings/waf_dl.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
"github.com/ebitengine/purego"
1919
)
2020

21-
// wafDl is the type wrapper for all C calls to the waf
21+
// WafDl is the type wrapper for all C calls to the waf
2222
// It uses `libwaf` to make C calls
2323
// All calls must go through this one-liner to be type safe
2424
// since purego calls are not type safe
@@ -71,11 +71,7 @@ func NewWafDl() (dl *WafDl, err error) {
7171
dl = &WafDl{symbols, handle}
7272

7373
// Try calling the waf to make sure everything is fine
74-
err = tryCall(func() error {
75-
dl.WafGetVersion()
76-
return nil
77-
})
78-
if err != nil {
74+
if _, err = tryCall(dl.WafGetVersion); err != nil {
7975
if closeErr := purego.Dlclose(handle); closeErr != nil {
8076
err = errors.Join(err, fmt.Errorf("error released the shared libddwaf library: %w", closeErr))
8177
}

waf.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type Diagnostics struct {
2828
Exclusions *DiagnosticEntry
2929
RulesOverrides *DiagnosticEntry
3030
RulesData *DiagnosticEntry
31+
ExclusionData *DiagnosticEntry
3132
Processors *DiagnosticEntry
3233
Scanners *DiagnosticEntry
3334
Version string
@@ -44,6 +45,7 @@ func (d *Diagnostics) TopLevelError() error {
4445
"exclusions": d.Exclusions,
4546
"rules_override": d.RulesOverrides,
4647
"rules_data": d.RulesData,
48+
"exclusion_data": d.ExclusionData,
4749
"processors": d.Processors,
4850
"scanners": d.Scanners,
4951
}

0 commit comments

Comments
 (0)