mirror of
https://github.com/go-gst/go-gst.git
synced 2025-09-28 21:02:23 +08:00
prevent use after frees with structures that are transfer:none
This commit is contained in:
@@ -95,9 +95,7 @@ func (m *Message) GetStructure() *Structure {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// The returned structure must not be freed. Applies to all methods.
|
return structureFromGlibNone(st)
|
||||||
// https://gstreamer.freedesktop.org/documentation/gstreamer/gstmessage.html#gst_message_parse_error_details
|
|
||||||
return wrapStructure(st)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseToError returns a new GError from this message instance. There are multiple
|
// parseToError returns a new GError from this message instance. There are multiple
|
||||||
|
@@ -17,6 +17,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ func NewStructure(name string) *Structure {
|
|||||||
cName := C.CString(name)
|
cName := C.CString(name)
|
||||||
defer C.free(unsafe.Pointer(cName))
|
defer C.free(unsafe.Pointer(cName))
|
||||||
structure := C.gst_structure_new_empty(cName)
|
structure := C.gst_structure_new_empty(cName)
|
||||||
return wrapStructure(structure)
|
return structureFromGlibFull(structure)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStructureFromString builds a new GstStructure from the given string.
|
// NewStructureFromString builds a new GstStructure from the given string.
|
||||||
@@ -46,7 +47,7 @@ func NewStructureFromString(stStr string) *Structure {
|
|||||||
if structure == nil {
|
if structure == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return wrapStructure(structure)
|
return structureFromGlibFull(structure)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalStructure will convert the given go struct into a GstStructure. Currently nested
|
// MarshalStructure will convert the given go struct into a GstStructure. Currently nested
|
||||||
@@ -190,22 +191,54 @@ var TypeStructure = glib.Type(C.gst_structure_get_type())
|
|||||||
|
|
||||||
var _ glib.ValueTransformer = &Structure{}
|
var _ glib.ValueTransformer = &Structure{}
|
||||||
|
|
||||||
|
func (s *Structure) copy() *C.GstStructure {
|
||||||
|
return C.gst_structure_copy(s.Instance())
|
||||||
|
}
|
||||||
|
|
||||||
// ToGValue implements a glib.ValueTransformer
|
// ToGValue implements a glib.ValueTransformer
|
||||||
func (s *Structure) ToGValue() (*glib.Value, error) {
|
func (s *Structure) ToGValue() (*glib.Value, error) {
|
||||||
val, err := glib.ValueInit(TypeStructure)
|
val, err := glib.ValueInit(TypeStructure)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
C.gst_value_set_structure(
|
C.gst_value_set_structure(
|
||||||
(*C.GValue)(unsafe.Pointer(val.GValue)),
|
(*C.GValue)(unsafe.Pointer(val.GValue)),
|
||||||
s.Instance(),
|
s.copy(),
|
||||||
)
|
)
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// marshalStructure is used to extract the GstStructure from a GValue.
|
||||||
|
func marshalStructure(p unsafe.Pointer) (interface{}, error) {
|
||||||
|
c := C.gst_value_get_structure(toGValue(p))
|
||||||
|
obj := (*C.GstStructure)(unsafe.Pointer(c))
|
||||||
|
return structureFromGlibNone(obj), nil
|
||||||
|
}
|
||||||
|
|
||||||
func wrapStructure(st *C.GstStructure) *Structure {
|
func wrapStructure(st *C.GstStructure) *Structure {
|
||||||
return &Structure{
|
return &Structure{
|
||||||
ptr: unsafe.Pointer(st),
|
ptr: unsafe.Pointer(st),
|
||||||
gType: glib.Type(st._type),
|
gType: glib.Type(st._type),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// structureFromGlibNone wraps a *C.GstStructure in a Structure after copying it.
|
||||||
|
// this is needed when the structure is returned from a function that does not transfer ownership.
|
||||||
|
func structureFromGlibNone(st *C.GstStructure) *Structure {
|
||||||
|
copy := C.gst_structure_copy(st)
|
||||||
|
|
||||||
|
return structureFromGlibFull(copy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// structureFromGlibFull wraps a *C.GstStructure in a Structure. This is used when the structure
|
||||||
|
// is returned by a function that transfers ownership to the caller.
|
||||||
|
func structureFromGlibFull(st *C.GstStructure) *Structure {
|
||||||
|
s := wrapStructure(st)
|
||||||
|
|
||||||
|
runtime.SetFinalizer(s, func(s *Structure) {
|
||||||
|
s.Free()
|
||||||
|
})
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
@@ -161,16 +161,6 @@ func ValueGetCapsFeatures(value *glib.Value) *CapsFeatures {
|
|||||||
return &CapsFeatures{native: feats}
|
return &CapsFeatures{native: feats}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValueGetStructure extracts the GstStructure from a glib.Value, or nil
|
|
||||||
// if one does not exist.
|
|
||||||
func ValueGetStructure(gval *glib.Value) *Structure {
|
|
||||||
st := C.gst_value_get_structure((*C.GValue)(unsafe.Pointer(gval.GValue)))
|
|
||||||
if st == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return wrapStructure(st)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValueIntersect calculates the intersection of two values. If the values have a non-empty intersection,
|
// ValueIntersect calculates the intersection of two values. If the values have a non-empty intersection,
|
||||||
// the value representing the intersection isreturned. Otherwise this function returns false. This function
|
// the value representing the intersection isreturned. Otherwise this function returns false. This function
|
||||||
// can also return false for any allocation errors.
|
// can also return false for any allocation errors.
|
||||||
|
@@ -461,12 +461,6 @@ func marshalCapsFeatures(p unsafe.Pointer) (interface{}, error) {
|
|||||||
return wrapCapsFeatures(obj), nil
|
return wrapCapsFeatures(obj), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func marshalStructure(p unsafe.Pointer) (interface{}, error) {
|
|
||||||
c := C.gst_value_get_structure(toGValue(p))
|
|
||||||
obj := (*C.GstStructure)(unsafe.Pointer(c))
|
|
||||||
return wrapStructure(obj), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshalContext(p unsafe.Pointer) (interface{}, error) {
|
func marshalContext(p unsafe.Pointer) (interface{}, error) {
|
||||||
c := C.g_value_get_object(toGValue(p))
|
c := C.g_value_get_object(toGValue(p))
|
||||||
obj := (*C.GstContext)(unsafe.Pointer(c))
|
obj := (*C.GstContext)(unsafe.Pointer(c))
|
||||||
|
Reference in New Issue
Block a user