Skip to content

Commit

Permalink
Merge pull request #954 from dcantah/fix-nilderef-jobs
Browse files Browse the repository at this point in the history
Fix nil dereference in jobobject.Create and Open
  • Loading branch information
dcantah authored Feb 26, 2021
2 parents 360f61d + 4c55e4c commit 7001566
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 9 deletions.
27 changes: 18 additions & 9 deletions internal/jobobject/jobobject.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ var (
ErrNotRegistered = errors.New("job is not registered to receive notifications")
)

// Options represents the set of configurable options when making or opening a job object.
type Options struct {
// `Name` specifies the name of the job object if a named job object is desired.
Name string
Expand All @@ -71,25 +72,28 @@ type Options struct {

// Create creates a job object.
//
// If name is an empty string, the job will not be assigned a name.
// If options.Name is an empty string, the job will not be assigned a name.
//
// If notifications are not enabled `PollNotifications` will return immediately with error `errNotRegistered`.
// If options.Notifications are not enabled `PollNotifications` will return immediately with error `errNotRegistered`.
//
// If `options` is nil, use default option values.
//
// Returns a JobObject structure and an error if there is one.
func Create(ctx context.Context, options *Options) (_ *JobObject, err error) {
var jobName *winapi.UnicodeString
if options == nil {
options = &Options{}
}

if options != nil && options.Name != "" {
var jobName *winapi.UnicodeString
if options.Name != "" {
jobName, err = winapi.NewUnicodeString(options.Name)
if err != nil {
return nil, err
}
}

var jobHandle windows.Handle
if options != nil && options.UseNTVariant {
if options.UseNTVariant {
oa := winapi.ObjectAttributes{
Length: unsafe.Sizeof(winapi.ObjectAttributes{}),
ObjectName: jobName,
Expand All @@ -100,7 +104,11 @@ func Create(ctx context.Context, options *Options) (_ *JobObject, err error) {
return nil, winapi.RtlNtStatusToDosError(status)
}
} else {
jobHandle, err = windows.CreateJobObject(nil, jobName.Buffer)
var jobNameBuf *uint16
if jobName != nil && jobName.Buffer != nil {
jobNameBuf = jobName.Buffer
}
jobHandle, err = windows.CreateJobObject(nil, jobNameBuf)
if err != nil {
return nil, err
}
Expand All @@ -118,7 +126,7 @@ func Create(ctx context.Context, options *Options) (_ *JobObject, err error) {

// If the IOCP we'll be using to receive messages for all jobs hasn't been
// created, create it and start polling.
if options != nil && options.Notifications {
if options.Notifications {
mq, err := setupNotifications(ctx, job)
if err != nil {
return nil, err
Expand All @@ -132,13 +140,14 @@ func Create(ctx context.Context, options *Options) (_ *JobObject, err error) {
// Open opens an existing job object with name provided in `options`. If no name is provided
// return an error since we need to know what job object to open.
//
// If notifications are not enabled `PollNotifications` will return immediately with error `errNotRegistered`.
// If options.Notifications is false `PollNotifications` will return immediately with error `errNotRegistered`.
//
// Returns a JobObject structure and an error if there is one.
func Open(ctx context.Context, options *Options) (_ *JobObject, err error) {
if options != nil && options.Name == "" {
if options == nil || (options != nil && options.Name == "") {
return nil, errors.New("no job object name specified to open")
}

unicodeJobName, err := winapi.NewUnicodeString(options.Name)
if err != nil {
return nil, err
Expand Down
30 changes: 30 additions & 0 deletions internal/jobobject/jobobject_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package jobobject

import (
"context"
"testing"
)

func TestJobNilOptions(t *testing.T) {
_, err := Create(context.Background(), nil)
if err != nil {
t.Fatal(err)
}
}

func TestJobCreateAndOpen(t *testing.T) {
var (
ctx = context.Background()
options = &Options{Name: "test"}
)

_, err := Create(ctx, options)
if err != nil {
t.Fatal(err)
}

_, err = Open(ctx, options)
if err != nil {
t.Fatal(err)
}
}

0 comments on commit 7001566

Please sign in to comment.