Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

panic: slice index out of range #328

Closed
mvberg opened this issue Sep 27, 2022 · 0 comments · Fixed by #329
Closed

panic: slice index out of range #328

mvberg opened this issue Sep 27, 2022 · 0 comments · Fixed by #329

Comments

@mvberg
Copy link
Contributor

mvberg commented Sep 27, 2022

Describe the bug

When attempting to access a go struct that contains a slice, the engine will panic on Execute when index is out of range and will not emit the error back to caller.

To Reproduce

Example Rule

rule SliceOORRule {
  when
    PriceSlice.Prices[4] > 10 // will cause panic if slice is empty
  then
    Log("Price number 4 is greater than 10");
    Retract("SliceOORRule");
}

Code

package examples

import (
	"testing"

	"github.com/hyperjumptech/grule-rule-engine/ast"
	"github.com/hyperjumptech/grule-rule-engine/builder"
	"github.com/hyperjumptech/grule-rule-engine/engine"
	"github.com/hyperjumptech/grule-rule-engine/pkg"
	"github.com/stretchr/testify/assert"
)

const (
	SliceOORRule = `
		rule SliceOORRule {
			when
				PriceSlice.Prices[4] > 10 // will cause panic
			then
				Log("Price number 4 is greater than 10");
				Retract("SliceOORRule");
		}`
)

type AUserSliceIssue struct {
	Prices []int
}

func TestMethodCall_SliceOOR(t *testing.T) {
	ps := &AUserSliceIssue{
		Prices: []int{1, 2, 3},
	}

	dataContext := ast.NewDataContext()
	err := dataContext.Add("PriceSlice", ps)
	assert.NoError(t, err)

	// Prepare knowledgebase library and load it with our rule.
	lib := ast.NewKnowledgeLibrary()
	rb := builder.NewRuleBuilder(lib)
	err = rb.BuildRuleFromResource("Test", "0.1.1", pkg.NewBytesResource([]byte(SliceOORRule)))
	assert.NoError(t, err)
	eng1 := &engine.GruleEngine{MaxCycle: 5}
	kb := lib.NewKnowledgeBaseInstance("Test", "0.1.1")
	err = eng1.Execute(dataContext, kb)
	assert.NoError(t, err)
}

Expected behavior

Would expect the engine to recover() from the panic and return the error back to the Execute caller.

Additional context

I will take a stab at a PR this week.

Stack Trace from Example Code

=== RUN   TestMethodCall_SliceOOR
--- FAIL: TestMethodCall_SliceOOR (0.01s)
panic: reflect: slice index out of range [recovered]
	panic: reflect: slice index out of range

goroutine 19 [running]:
testing.tRunner.func1.2({0x14ad1e0, 0x1688110})
	C:/Program Files/Go/src/testing/testing.go:1396 +0x24e
testing.tRunner.func1()
	C:/Program Files/Go/src/testing/testing.go:1399 +0x39f
panic({0x14ad1e0, 0x1688110})
	C:/Program Files/Go/src/runtime/panic.go:884 +0x212
reflect.Value.Index({0x14a2760?, 0xc0000a4ac8?, 0xc000207650?}, 0xebe767?)
	C:/Program Files/Go/src/reflect/value.go:1412 +0x16d
github.com/hyperjumptech/grule-rule-engine/model.(*GoValueNode).GetArrayValueAt(0xc0001562c0?, 0xc00034c240?)
	c:/Users/Mike/git/grule-rule-engine/model/GoDataAccessLayer.go:101 +0x45
github.com/hyperjumptech/grule-rule-engine/model.(*GoValueNode).GetChildNodeByIndex(0xc0002e1c40, 0x1693c60?)
	c:/Users/Mike/git/grule-rule-engine/model/GoDataAccessLayer.go:109 +0x54
github.com/hyperjumptech/grule-rule-engine/ast.(*Variable).Evaluate(0xc000331180, {0x1693c60, 0xc00011f860}, 0x100?)
	c:/Users/Mike/git/grule-rule-engine/ast/Variable.go:242 +0x272
github.com/hyperjumptech/grule-rule-engine/ast.(*ExpressionAtom).Evaluate(0xc000127560, {0x1693c60?, 0xc00011f860?}, 0xc000357180?)
	c:/Users/Mike/git/grule-rule-engine/ast/ExpressionAtom.go:269 +0xd5d
github.com/hyperjumptech/grule-rule-engine/ast.(*Expression).Evaluate(0xc000331110, {0x1693c60?, 0xc00011f860?}, 0xc0002e1c00?)
	c:/Users/Mike/git/grule-rule-engine/ast/Expression.go:279 +0x9dc
github.com/hyperjumptech/grule-rule-engine/ast.(*Expression).Evaluate(0xc0003310a0, {0x1693c60, 0xc00011f860}, 0x14d7460?)
	c:/Users/Mike/git/grule-rule-engine/ast/Expression.go:305 +0xa6
github.com/hyperjumptech/grule-rule-engine/ast.(*WhenScope).Evaluate(...)
	c:/Users/Mike/git/grule-rule-engine/ast/WhenScope.go:122
github.com/hyperjumptech/grule-rule-engine/ast.(*RuleEntry).Evaluate(0xc0000e0e40, {0x1693c60?, 0xc00011f860?}, 0x0?)
	c:/Users/Mike/git/grule-rule-engine/ast/RuleEntry.go:167 +0x45
github.com/hyperjumptech/grule-rule-engine/engine.(*GruleEngine).ExecuteWithContext(0xc000207e38, {0x168e270, 0xc0000a60f8}, {0x1693c60?, 0xc00011f860}, 0xc000347770)
	c:/Users/Mike/git/grule-rule-engine/engine/GruleEngine.go:157 +0x7f9
github.com/hyperjumptech/grule-rule-engine/engine.(*GruleEngine).Execute(...)
	c:/Users/Mike/git/grule-rule-engine/engine/GruleEngine.go:80
github.com/hyperjumptech/grule-rule-engine/examples.TestMethodCall_SliceOOR(0x0?)
	c:/Users/Mike/git/grule-rule-engine/examples/SliceIndexOutOfRangePanic_test.go:58 +0x310
testing.tRunner(0xc00008da00, 0x15d5338)
	C:/Program Files/Go/src/testing/testing.go:1446 +0x10b
created by testing.(*T).Run
	C:/Program Files/Go/src/testing/testing.go:1493 +0x35f
FAIL	github.com/hyperjumptech/grule-rule-engine/examples	0.067s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant