@@ -125,9 +125,13 @@ func (o *Object) runlock() {
125
125
}
126
126
}
127
127
128
+ func (o * Object ) Absorb (source * Object ) {
129
+ o .AbsorbEx (source , false )
130
+ }
131
+
128
132
// Absorbs data and Pwn relationships from another object, sucking the soul out of it
129
133
// The sources empty shell should be discarded afterwards (i.e. not appear in an Objects collection)
130
- func (o * Object ) Absorb (source * Object ) {
134
+ func (o * Object ) AbsorbEx (source * Object , fast bool ) {
131
135
if o == source {
132
136
log .Fatal ().Msg ("Can't absorb myself" )
133
137
}
@@ -140,49 +144,53 @@ func (o *Object) Absorb(source *Object) {
140
144
defer o .unlock ()
141
145
142
146
target := o
143
- for attr , values := range source .values {
144
- var val AttributeValues
145
- tval := target .attr (attr )
146
- sval := values
147
-
148
- if tval .Len () == 0 {
149
- val = sval
150
- } else if sval .Len () == 0 {
151
- panic (fmt .Sprintf ("Attribute %v with ZERO LENGTH data failure" , attr .String ()))
152
- } else if tval .Len () == 1 && sval .Len () == 1 {
153
- tvalue := tval .Slice ()[0 ]
154
- svalue := sval .Slice ()[0 ]
155
-
156
- if CompareAttributeValues (tvalue , svalue ) {
157
- val = tval // They're the same, so pick any
147
+
148
+ // Fast mode does not merge values, it just relinks the source to the target
149
+ if ! fast {
150
+ for attr , values := range source .values {
151
+ var val AttributeValues
152
+ tval := target .attr (attr )
153
+ sval := values
154
+
155
+ if tval .Len () == 0 {
156
+ val = sval
157
+ } else if sval .Len () == 0 {
158
+ panic (fmt .Sprintf ("Attribute %v with ZERO LENGTH data failure" , attr .String ()))
159
+ } else if tval .Len () == 1 && sval .Len () == 1 {
160
+ tvalue := tval .Slice ()[0 ]
161
+ svalue := sval .Slice ()[0 ]
162
+
163
+ if CompareAttributeValues (tvalue , svalue ) {
164
+ val = tval // They're the same, so pick any
165
+ } else {
166
+ // They're not the same, join them
167
+ val = AttributeValueSlice {tvalue , svalue }
168
+ }
158
169
} else {
159
- // They're not the same, join them
160
- val = AttributeValueSlice { tvalue , svalue }
161
- }
162
- } else {
163
- // One or more of them have more than one value, do it the hard way
164
- tvalslice := tval . Slice ( )
165
- svalslice := sval . Slice ()
166
-
167
- resultingvalues := make ([] AttributeValue , tval . Len ())
168
- copy ( resultingvalues , tvalslice )
169
-
170
- for _ , svalue := range svalslice {
171
- var alreadythere bool
172
- compareloop:
173
- for _ , tvalue := range tvalslice {
174
- if CompareAttributeValues ( svalue , tvalue ) { // Crap!!
175
- alreadythere = true
176
- break compareloop
170
+ // One or more of them have more than one value, do it the hard way
171
+ tvalslice := tval . Slice ()
172
+ svalslice := sval . Slice ()
173
+
174
+ resultingvalues := make ([] AttributeValue , tval . Len ())
175
+ copy ( resultingvalues , tvalslice )
176
+
177
+ for _ , svalue := range svalslice {
178
+ var alreadythere bool
179
+ compareloop:
180
+ for _ , tvalue := range tvalslice {
181
+ if CompareAttributeValues ( svalue , tvalue ) { // Crap!!
182
+ alreadythere = true
183
+ break compareloop
184
+ }
185
+ }
186
+ if ! alreadythere {
187
+ resultingvalues = append ( resultingvalues , svalue )
177
188
}
178
189
}
179
- if ! alreadythere {
180
- resultingvalues = append (resultingvalues , svalue )
181
- }
190
+ val = AttributeValueSlice (resultingvalues )
182
191
}
183
- val = AttributeValueSlice ( resultingvalues )
192
+ target . set ( attr , val )
184
193
}
185
- target .set (attr , val )
186
194
}
187
195
188
196
for pwntarget , methods := range source .CanPwn {
@@ -234,15 +242,15 @@ func (o *Object) Absorb(source *Object) {
234
242
source .memberofrecursive = nil
235
243
236
244
for _ , child := range source .children {
237
- target .Adopt (child )
245
+ target .adopt (child )
238
246
}
239
247
240
248
// If the source has a parent, but the target doesn't we assimilate that role (muhahaha)
241
249
if source .parent != nil {
242
250
if target .parent == nil {
243
251
target .ChildOf (source .parent )
244
252
}
245
- source .parent .RemoveChild (source )
253
+ source .parent .removeChild (source )
246
254
source .parent = nil
247
255
}
248
256
@@ -472,7 +480,7 @@ func (o *Object) OneAttrString(attr Attribute) string {
472
480
return ""
473
481
}
474
482
if ao , ok := a .(AttributeValueOne ); ok {
475
- return ao .String ()
483
+ return ao .Value . String ()
476
484
}
477
485
if a .Len () == 1 {
478
486
log .Warn ().Msg ("Inefficient attribute storage - multival used for one value ..." )
@@ -772,6 +780,8 @@ func (o *Object) setFlex(flexinit ...interface{}) {
772
780
continue
773
781
}
774
782
data = append (data , v )
783
+ case AttributeValueOne :
784
+ data = append (data , v .Value )
775
785
case AttributeValueSlice :
776
786
for _ , value := range v {
777
787
if ignoreblanks && value .IsZero () {
@@ -1082,13 +1092,24 @@ func (o *Object) Adopt(child *Object) {
1082
1092
1083
1093
child .lock ()
1084
1094
if child .parent != nil {
1085
- child .parent .RemoveChild (child )
1095
+ child .parent .lock ()
1096
+ child .parent .removeChild (child )
1097
+ child .parent .unlock ()
1086
1098
}
1087
1099
child .parent = o
1088
1100
child .unlock ()
1089
1101
}
1090
1102
1091
- func (o * Object ) RemoveChild (child * Object ) {
1103
+ func (o * Object ) adopt (child * Object ) {
1104
+ o .children = append (o .children , child )
1105
+
1106
+ if child .parent != nil {
1107
+ child .parent .removeChild (child )
1108
+ }
1109
+ child .parent = o
1110
+ }
1111
+
1112
+ func (o * Object ) removeChild (child * Object ) {
1092
1113
for i , curchild := range o .children {
1093
1114
if curchild == child {
1094
1115
if len (o .children ) == 1 {
0 commit comments