Skip to content

Copy the return value using g_value_copy in goMarshal to avoid double free and invalid memory reads #9

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
Deprecated. Use [go-glib](https://github.com/go-gst/go-glib) instead.

# go-glib
Glib bindings for go. Originally forked from gotk3/gotk3.
2 changes: 1 addition & 1 deletion glib/glib.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ func goMarshal(closure *C.GClosure, retValue *C.GValue,
fmt.Fprintf(os.Stderr,
"cannot save callback return value: %v", err)
} else {
*retValue = *g.native()
C.g_value_copy(g.native(), retValue)
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions glib/gparamspec.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ func ToParamSpec(paramspec unsafe.Pointer) *ParamSpec {
}
}

// newParamSpec creates a new ParamSpec from a GParamSpec pointer.
func newParamSpec(p *C.GParamSpec) *ParamSpec {
return &ParamSpec{paramSpec: p}
}

// Name returns the name of this parameter.
func (p *ParamSpec) Name() string {
return C.GoString(C.g_param_spec_get_name(p.paramSpec))
Expand Down
18 changes: 18 additions & 0 deletions glib/gvalue.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,13 @@ func gValue(v interface{}) (gvalue *Value, err error) {
val.SetInstance(uintptr(unsafe.Pointer(e.GObject)))
return val, nil

case *ParamSpec:
val, err := ValueInit(TYPE_PARAM)
if err != nil {
return nil, err
}
return val, nil

default:
/* Try this since above doesn't catch constants under other types */
rval := reflect.ValueOf(v)
Expand Down Expand Up @@ -336,6 +343,7 @@ var gValueMarshalers = marshalMap{marshalMap: map[Type]GValueMarshaler{
TYPE_BOXED: marshalBoxed,
TYPE_OBJECT: marshalObject,
TYPE_VARIANT: marshalVariant,
TYPE_PARAM: marshalParam,
}}

func (m *marshalMap) register(tm []TypeMarshaler) {
Expand Down Expand Up @@ -476,6 +484,11 @@ func marshalVariant(p uintptr) (interface{}, error) {
return nil, errors.New("variant conversion not yet implemented")
}

func marshalParam(p uintptr) (interface{}, error) {
c := C.g_value_get_param((*C.GValue)(unsafe.Pointer(p)))
return newParamSpec((*C.GParamSpec)(c)), nil
}

// GoValue converts a Value to comparable Go type. GoValue()
// returns a non-nil error if the conversion was unsuccessful. The
// returned interface{} must be type asserted as the actual Go
Expand Down Expand Up @@ -562,6 +575,11 @@ func (v *Value) SetEnum(e int) {
C.g_value_set_enum(v.native(), C.gint(e))
}

// SetParam is a wrapper around g_value_set_param().
func (v *Value) SetParam(p *ParamSpec) {
C.g_value_set_param(v.native(), p.paramSpec)
}

// GetPointer is a wrapper around g_value_get_pointer().
func (v *Value) GetPointer() unsafe.Pointer {
return unsafe.Pointer(C.g_value_get_pointer(v.native()))
Expand Down