Skip to content

Commit 0b5918c

Browse files
authored
Merge pull request #7739 from headius/no_marshal_finalizer
Don't try to marshal non-serializable variables
2 parents fcce721 + 7065582 commit 0b5918c

File tree

9 files changed

+34
-7
lines changed

9 files changed

+34
-7
lines changed

core/src/main/java/org/jruby/RubyBasicObject.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,20 @@ public List<Variable<Object>> getVariableList() {
13311331
return list;
13321332
}
13331333

1334+
/**
1335+
* @see IRubyObject#getMarshalVariableList()
1336+
*/
1337+
public List<Variable<Object>> getMarshalVariableList() {
1338+
Map<String, VariableAccessor> ivarAccessors = metaClass.getVariableAccessorsForRead();
1339+
ArrayList<Variable<Object>> list = new ArrayList<>(ivarAccessors.size());
1340+
for (Map.Entry<String, VariableAccessor> entry : ivarAccessors.entrySet()) {
1341+
Object value = entry.getValue().get(this);
1342+
if (value == null || !(value instanceof Serializable)) continue;
1343+
list.add(new VariableEntry<>(entry.getKey(), value));
1344+
}
1345+
return list;
1346+
}
1347+
13341348
/**
13351349
* Gets a name list of all variables in this object.
13361350
*/

core/src/main/java/org/jruby/RubyClass.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,7 @@ public void marshalTo(Ruby runtime, Object obj, RubyClass type, MarshalStream ma
12691269
IRubyObject object = (IRubyObject) obj;
12701270

12711271
marshalStream.registerLinkTarget(object);
1272-
marshalStream.dumpVariables(object.getVariableList());
1272+
marshalStream.dumpVariables(object.getMarshalVariableList());
12731273
}
12741274

12751275
@Override

core/src/main/java/org/jruby/RubyException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ public static RubyClass createExceptionClass(Ruby runtime) {
170170
public void marshalTo(Ruby runtime, RubyException exc, RubyClass type,
171171
MarshalStream marshalStream) throws IOException {
172172
marshalStream.registerLinkTarget(exc);
173-
List<Variable<Object>> attrs = exc.getVariableList();
173+
List<Variable<Object>> attrs = exc.getMarshalVariableList();
174174
attrs.add(new VariableEntry<>("mesg", exc.getMessage()));
175175
attrs.add(new VariableEntry<>("bt", exc.getBacktrace()));
176176
marshalStream.dumpVariables(attrs);

core/src/main/java/org/jruby/RubyProcess.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ public void marshalTo(Ruby runtime, Object obj, RubyClass type,
172172
RubyStatus status = (RubyStatus) obj;
173173

174174
marshalStream.registerLinkTarget(status);
175-
List<Variable<Object>> attrs = status.getVariableList();
175+
List<Variable<Object>> attrs = status.getMarshalVariableList();
176176

177177
attrs.add(new VariableEntry("status", runtime.newFixnum(status.status)));
178178
attrs.add(new VariableEntry("pid", runtime.newFixnum(status.pid)));

core/src/main/java/org/jruby/RubyRange.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1143,7 +1143,7 @@ public void marshalTo(Ruby runtime, Object obj, RubyClass type,
11431143
RubyRange range = (RubyRange) obj;
11441144

11451145
marshalStream.registerLinkTarget(range);
1146-
List<Variable<Object>> attrs = range.getVariableList();
1146+
List<Variable<Object>> attrs = range.getMarshalVariableList();
11471147

11481148
attrs.add(new VariableEntry<Object>("excl", range.isExclusive ? runtime.getTrue() : runtime.getFalse()));
11491149
attrs.add(new VariableEntry<Object>("begin", range.begin));

core/src/main/java/org/jruby/RubySystemCallError.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public void marshalTo(Ruby runtime, Object obj, RubyClass type,
139139
RubySystemCallError exc = (RubySystemCallError) obj;
140140
marshalStream.registerLinkTarget(exc);
141141

142-
List<Variable<Object>> attrs = exc.getVariableList();
142+
List<Variable<Object>> attrs = exc.getMarshalVariableList();
143143
attrs.add(new VariableEntry<Object>(
144144
"mesg", exc.message == null ? runtime.getNil() : exc.message));
145145
attrs.add(new VariableEntry<Object>("errno", exc.errno));

core/src/main/java/org/jruby/runtime/builtin/IRubyObject.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,13 @@ static IRubyObject[] array(int length) {
361361
*/
362362
List<Variable<Object>> getVariableList();
363363

364+
/**
365+
* @return a list of all marshalable variables (ivar/cvar/constant/internal)
366+
*/
367+
default List<Variable<Object>> getMarshalVariableList() {
368+
return getVariableList();
369+
}
370+
364371
//
365372
// INSTANCE VARIABLE METHODS
366373
//

core/src/main/java/org/jruby/runtime/marshal/MarshalStream.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ private List<Variable<Object>> getVariables(IRubyObject value) throws IOExceptio
161161
// object has instance vars and isn't a class, get a snapshot to be marshalled
162162
// and output the ivar header here
163163

164-
variables = value.getVariableList();
164+
variables = value.getMarshalVariableList();
165165

166166
// check if any of those variables were actually set
167167
if (variables.size() > 0 || shouldMarshalEncoding(value)) {
@@ -380,7 +380,7 @@ private void userCommon(IRubyObject value, CacheEntry entry) throws IOException
380380

381381
List<Variable<Object>> variables = null;
382382
if (marshaled.hasVariables()) {
383-
variables = marshaled.getVariableList();
383+
variables = marshaled.getMarshalVariableList();
384384
if (variables.size() > 0) {
385385
write(TYPE_IVAR);
386386
} else {

spec/ruby/core/marshal/dump_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,12 @@ def obj.foo; end
458458
obj = MarshalSpec::BasicObjectSubWithRespondToFalse.new
459459
Marshal.dump(obj).should == "\x04\bo:2MarshalSpec::BasicObjectSubWithRespondToFalse\x00"
460460
end
461+
462+
it "dumps without marshaling any attached finalizer" do
463+
obj = Object.new
464+
ObjectSpace.define_finalizer(obj, &:itself)
465+
Marshal.load(Marshal.dump(obj)).class.should == Object
466+
end
461467
end
462468

463469
describe "with a Range" do

0 commit comments

Comments
 (0)