Skip caller-allocates out-params instead of miscompiling them
GIR caller-allocates out-params (char *outbuf, gunichar *result) require the caller to allocate and size the buffer, unlike callee-allocates T** out-params where the callee fills in the pointee. The out-param marshalling declared a single Swift scalar and passed its address, which is correct only for the callee-allocates shape; for caller-allocates, C wrote buffer payload past the one-element slot (g_unichar_fully_decompose) or the payload was reinterpreted as a pointer and dereferenced (g_unichar_to_utf8, segfault). GIR carries no buffer-size field, so these are now skipped rather than generated. The guard also reclassifies time_val_from_iso8601/signal_query/type_query from plainRecord to the accurate caller-allocates reason.
This commit is contained in:
parent
16e5449cad
commit
b61512c4eb
3 changed files with 34 additions and 7 deletions
|
|
@ -699,6 +699,21 @@ func planParameters(
|
|||
|
||||
// Direction check
|
||||
if param.direction == .out {
|
||||
// Caller-allocates out-params (`char *outbuf`, `gunichar *result`)
|
||||
// hand the C function a pointer to storage the CALLER must size and
|
||||
// own — unlike callee-allocates out-params (`T **out`) where the
|
||||
// callee fills in the pointee. Our out-param marshalling declares a
|
||||
// single Swift scalar and passes its address, which is correct only
|
||||
// for the callee-allocates shape; for caller-allocates it lets C
|
||||
// write buffer payload past a one-element slot (memory corruption)
|
||||
// or reinterpret payload as a pointer (segfault, e.g.
|
||||
// g_unichar_to_utf8). GIR carries no buffer-size field, so there is
|
||||
// nothing to allocate against — skip rather than guess.
|
||||
if param.callerAllocates {
|
||||
return .skip(SkipEntry(symbol: "", cIdentifier: nil,
|
||||
reason: .outParameter,
|
||||
detail: "caller-allocates out-param '\(param.name)' (no buffer size in GIR)"))
|
||||
}
|
||||
// Out-params are collected and returned as Swift values rather than
|
||||
// passed as arguments. Map the VALUE type (not the pointer-to-pointer).
|
||||
let mappingResult = Result { try map(param.type, nullable: param.isNullable,
|
||||
|
|
|
|||
|
|
@ -2774,8 +2774,8 @@
|
|||
},
|
||||
{
|
||||
"cIdentifier" : "g_time_val_from_iso8601",
|
||||
"detail" : "out-param 'time_': 'GLib.TimeVal' has no GType registration or lifetime functions",
|
||||
"reason" : "plainRecord",
|
||||
"detail" : "caller-allocates out-param 'time_' (no buffer size in GIR)",
|
||||
"reason" : "outParameter",
|
||||
"symbol" : "GLib.time_val_from_iso8601"
|
||||
},
|
||||
{
|
||||
|
|
@ -2850,6 +2850,18 @@
|
|||
"reason" : "arrayWithoutLength",
|
||||
"symbol" : "GLib.ucs4_to_utf8"
|
||||
},
|
||||
{
|
||||
"cIdentifier" : "g_unichar_fully_decompose",
|
||||
"detail" : "caller-allocates out-param 'result' (no buffer size in GIR)",
|
||||
"reason" : "outParameter",
|
||||
"symbol" : "GLib.unichar_fully_decompose"
|
||||
},
|
||||
{
|
||||
"cIdentifier" : "g_unichar_to_utf8",
|
||||
"detail" : "caller-allocates out-param 'outbuf' (no buffer size in GIR)",
|
||||
"reason" : "outParameter",
|
||||
"symbol" : "GLib.unichar_to_utf8"
|
||||
},
|
||||
{
|
||||
"cIdentifier" : "g_unicode_canonical_decomposition",
|
||||
"detail" : "parameter 'result_len' C type 'gsize*' is a pointer",
|
||||
|
|
@ -3063,7 +3075,7 @@
|
|||
],
|
||||
"module" : "GLib",
|
||||
"stats" : {
|
||||
"boundCallables" : 335,
|
||||
"boundCallables" : 333,
|
||||
"boundTypes" : 246,
|
||||
"totalCallables" : 724,
|
||||
"totalTypes" : 367
|
||||
|
|
|
|||
|
|
@ -794,8 +794,8 @@
|
|||
},
|
||||
{
|
||||
"cIdentifier" : "g_signal_query",
|
||||
"detail" : "out-param 'query': 'GObject.SignalQuery' has no GType registration or lifetime functions",
|
||||
"reason" : "plainRecord",
|
||||
"detail" : "caller-allocates out-param 'query' (no buffer size in GIR)",
|
||||
"reason" : "outParameter",
|
||||
"symbol" : "GObject.signal_query"
|
||||
},
|
||||
{
|
||||
|
|
@ -974,8 +974,8 @@
|
|||
},
|
||||
{
|
||||
"cIdentifier" : "g_type_query",
|
||||
"detail" : "out-param 'query': 'GObject.TypeQuery' has no GType registration or lifetime functions",
|
||||
"reason" : "plainRecord",
|
||||
"detail" : "caller-allocates out-param 'query' (no buffer size in GIR)",
|
||||
"reason" : "outParameter",
|
||||
"symbol" : "GObject.type_query"
|
||||
},
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue