mirror of
https://github.com/go-gst/go-gst.git
synced 2025-09-26 20:11:18 +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
|
||||
}
|
||||
|
||||
// The returned structure must not be freed. Applies to all methods.
|
||||
// https://gstreamer.freedesktop.org/documentation/gstreamer/gstmessage.html#gst_message_parse_error_details
|
||||
return wrapStructure(st)
|
||||
return structureFromGlibNone(st)
|
||||
}
|
||||
|
||||
// parseToError returns a new GError from this message instance. There are multiple
|
||||
|
@@ -17,6 +17,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
@@ -35,7 +36,7 @@ func NewStructure(name string) *Structure {
|
||||
cName := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cName))
|
||||
structure := C.gst_structure_new_empty(cName)
|
||||
return wrapStructure(structure)
|
||||
return structureFromGlibFull(structure)
|
||||
}
|
||||
|
||||
// NewStructureFromString builds a new GstStructure from the given string.
|
||||
@@ -46,7 +47,7 @@ func NewStructureFromString(stStr string) *Structure {
|
||||
if structure == nil {
|
||||
return nil
|
||||
}
|
||||
return wrapStructure(structure)
|
||||
return structureFromGlibFull(structure)
|
||||
}
|
||||
|
||||
// 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{}
|
||||
|
||||
func (s *Structure) copy() *C.GstStructure {
|
||||
return C.gst_structure_copy(s.Instance())
|
||||
}
|
||||
|
||||
// ToGValue implements a glib.ValueTransformer
|
||||
func (s *Structure) ToGValue() (*glib.Value, error) {
|
||||
val, err := glib.ValueInit(TypeStructure)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
C.gst_value_set_structure(
|
||||
(*C.GValue)(unsafe.Pointer(val.GValue)),
|
||||
s.Instance(),
|
||||
s.copy(),
|
||||
)
|
||||
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 {
|
||||
return &Structure{
|
||||
ptr: unsafe.Pointer(st),
|
||||
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}
|
||||
}
|
||||
|
||||
// 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,
|
||||
// the value representing the intersection isreturned. Otherwise this function returns false. This function
|
||||
// can also return false for any allocation errors.
|
||||
|
@@ -461,12 +461,6 @@ func marshalCapsFeatures(p unsafe.Pointer) (interface{}, error) {
|
||||
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) {
|
||||
c := C.g_value_get_object(toGValue(p))
|
||||
obj := (*C.GstContext)(unsafe.Pointer(c))
|
||||
|
Reference in New Issue
Block a user