Skip to content

Commit

Permalink
check function param length and type (#638)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnRoesler authored Dec 14, 2023
1 parent b0fdf55 commit 80a4f43
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
2 changes: 2 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ var (
ErrMonthlyJobMinutesSeconds = fmt.Errorf("gocron: MonthlyJob: atTimes minutes and seconds must be between 0 and 59 inclusive")
ErrNewJobTaskNil = fmt.Errorf("gocron: NewJob: Task must not be nil")
ErrNewJobTaskNotFunc = fmt.Errorf("gocron: NewJob: Task.Function must be of kind reflect.Func")
ErrNewJobWrongNumberOfParameters = fmt.Errorf("gocron: NewJob: Number of provided parameters does not match expected")
ErrNewJobWrongTypeOfParameters = fmt.Errorf("gocron: NewJob: Type of provided parameters does not match expected")
ErrStopExecutorTimedOut = fmt.Errorf("gocron: timed out waiting for executor to stop")
ErrStopJobsTimedOut = fmt.Errorf("gocron: timed out waiting for jobs to finish")
ErrStopSchedulerTimedOut = fmt.Errorf("gocron: timed out waiting for scheduler to stop")
Expand Down
19 changes: 19 additions & 0 deletions scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,25 @@ func (s *scheduler) addOrUpdateJob(id uuid.UUID, definition JobDefinition, taskW
return nil, ErrNewJobTaskNotFunc
}

expectedParameterLength := taskFunc.Type().NumIn()
if len(tsk.parameters) != expectedParameterLength {
return nil, ErrNewJobWrongNumberOfParameters
}

for i := 0; i < expectedParameterLength; i++ {
t1 := reflect.TypeOf(tsk.parameters[i]).Kind()
if t1 == reflect.Interface || t1 == reflect.Pointer {
t1 = reflect.TypeOf(tsk.parameters[i]).Elem().Kind()
}
t2 := reflect.New(taskFunc.Type().In(i)).Elem().Kind()
if t2 == reflect.Interface || t2 == reflect.Pointer {
t2 = reflect.Indirect(reflect.ValueOf(taskFunc.Type().In(i))).Kind()
}
if t1 != t2 {
return nil, ErrNewJobWrongTypeOfParameters
}
}

j.name = runtime.FuncForPC(taskFunc.Pointer()).Name()
j.function = tsk.function
j.parameters = tsk.parameters
Expand Down
62 changes: 62 additions & 0 deletions scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,8 @@ func TestScheduler_NewJobTask(t *testing.T) {
goleak.VerifyNone(t)

testFuncPtr := func() {}
testFuncWithParams := func(one, two string) {}
testStruct := struct{}{}

tests := []struct {
name string
Expand All @@ -774,6 +776,66 @@ func TestScheduler_NewJobTask(t *testing.T) {
NewTask(&testFuncPtr),
nil,
},
{
"parameter number does not match",
NewTask(testFuncWithParams, "one"),
ErrNewJobWrongNumberOfParameters,
},
{
"parameter type does not match",
NewTask(testFuncWithParams, "one", 2),
ErrNewJobWrongTypeOfParameters,
},
{
"parameter number does not match - ptr",
NewTask(&testFuncWithParams, "one"),
ErrNewJobWrongNumberOfParameters,
},
{
"parameter type does not match - ptr",
NewTask(&testFuncWithParams, "one", 2),
ErrNewJobWrongTypeOfParameters,
},
{
"all good struct",
NewTask(func(one struct{}) {}, struct{}{}),
nil,
},
{
"all good interface",
NewTask(func(one interface{}) {}, struct{}{}),
nil,
},
{
"all good any",
NewTask(func(one any) {}, struct{}{}),
nil,
},
{
"all good slice",
NewTask(func(one []struct{}) {}, []struct{}{}),
nil,
},
{
"all good chan",
NewTask(func(one chan struct{}) {}, make(chan struct{})),
nil,
},
{
"all good pointer",
NewTask(func(one *struct{}) {}, &testStruct),
nil,
},
{
"all good map",
NewTask(func(one map[string]struct{}) {}, make(map[string]struct{})),
nil,
},
{
"all good",
NewTask(&testFuncWithParams, "one", "two"),
nil,
},
}

for _, tt := range tests {
Expand Down

0 comments on commit 80a4f43

Please sign in to comment.