Pārlūkot izejas kodu

fix: transfer delegate ownership in PropertyMappingBuilder ((owned) casts) — valac emits copy-and-destroy for plain param-to-owned-field delegate assignments, freeing the stored closure when the builder method returns and leaving every long-lived PropertyMapper reading freed memory on map_into/map_from (the intermittent, layout-dependent SIGSEGV that surfaced far from the cause, e.g. during Statum slot signing)

clanker 5 dienas atpakaļ
vecāks
revīzija
25020cc4a9
1 mainītis faili ar 15 papildinājumiem un 4 dzēšanām
  1. 15 4
      src/lib/Mapping/PropertyMapper.vala

+ 15 - 4
src/lib/Mapping/PropertyMapper.vala

@@ -80,6 +80,17 @@ namespace Invercargill.Mapping {
 
 
     private class PropertyMapping<T> {
     private class PropertyMapping<T> {
         public string name;
         public string name;
+        // Delegate fields are owned (the default) — but valac only
+        // emits the ownership transfer (storing the closure's destroy
+        // notify instead of destroying it at scope exit) for assignments
+        // marked (owned) or lambda literals. The plain param-to-field
+        // assignments below therefore used to free every stored closure
+        // the moment the builder method returned, leaving long-lived
+        // mappers with dangling setter/getter targets — a use-after-free
+        // read on each map_into/map_from that only faulted when the
+        // allocator reused the block (intermittent, layout-dependent
+        // SIGSEGVs far away from the cause, e.g. during Statum slot
+        // signing).
         public PropertyGetter<T, Element> getter;
         public PropertyGetter<T, Element> getter;
         public PropertySetter<T, Element> setter;
         public PropertySetter<T, Element> setter;
         public PropertyPredicate<T>? null_check;
         public PropertyPredicate<T>? null_check;
@@ -190,22 +201,22 @@ namespace Invercargill.Mapping {
         }
         }
 
 
         public PropertyMappingBuilder<T> null_when(owned PropertyPredicate<T> predicate) {
         public PropertyMappingBuilder<T> null_when(owned PropertyPredicate<T> predicate) {
-            mapping.null_check = predicate;
+            mapping.null_check = (owned)predicate;
             return this;
             return this;
         }
         }
 
 
         public PropertyMappingBuilder<T> undefined_when(owned PropertyPredicate<T> predicate) {
         public PropertyMappingBuilder<T> undefined_when(owned PropertyPredicate<T> predicate) {
-            mapping.undefined_check = predicate;
+            mapping.undefined_check = (owned)predicate;
             return this;
             return this;
         }
         }
 
 
         public PropertyMappingBuilder<T> when_null(owned PropertyDefaultSetter<T> setter) {
         public PropertyMappingBuilder<T> when_null(owned PropertyDefaultSetter<T> setter) {
-            mapping.null_setter = setter;
+            mapping.null_setter = (owned)setter;
             return this;
             return this;
         }
         }
         
         
         public PropertyMappingBuilder<T> when_undefined(owned PropertyDefaultSetter<T> setter) {
         public PropertyMappingBuilder<T> when_undefined(owned PropertyDefaultSetter<T> setter) {
-            mapping.undefined_setter = setter;
+            mapping.undefined_setter = (owned)setter;
             return this;
             return this;
         }
         }