Skip to content

Commit 5aa88b6

Browse files
committed
Now setters for RealmObject and RealmList have a check if the value is a valid object or not (realm#1749).
1 parent e490afe commit 5aa88b6

5 files changed

Lines changed: 146 additions & 1 deletion

File tree

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Fixed a bug making it impossible to read Realms created using primary keys and created by iOS (#1703).
55
* Fixed some memory leaks when an Exception is thrown (#1730).
66
* RealmQuery.isNull() and RealmQuery.isNotNull() now throw IllegalArgumentException instead of RealmError if the fieldname is a linked field and the last element is a link (#1693).
7+
* Setters in managed object for RealmObject and RealmList now throw IllegalArgumentException if the value contains an invalid(standalone, removed, closed) object (#1749).
78

89
0.84.1
910
* Updated Realm Core to 0.94.4

realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,9 @@ private void emitAccessors(JavaWriter writer) throws IOException {
286286
writer.emitStatement("row.nullifyLink(%s)", fieldIndexVariableReference(field));
287287
writer.emitStatement("return");
288288
writer.endControlFlow();
289+
writer.beginControlFlow("if (!value.isValid())");
290+
writer.emitStatement("throw new IllegalArgumentException(\"'value' is not a valid managed object.\")");
291+
writer.endControlFlow();
289292
writer.emitStatement("row.setLink(%s, value.row.getIndex())", fieldIndexVariableReference(field));
290293
writer.endMethod();
291294
} else if (Utils.isRealmList(field)) {
@@ -327,7 +330,10 @@ private void emitAccessors(JavaWriter writer) throws IOException {
327330
writer.emitStatement("return");
328331
writer.endControlFlow();
329332
writer.beginControlFlow("for (RealmObject linkedObject : (RealmList<? extends RealmObject>) value)");
330-
writer.emitStatement("links.add(linkedObject.row.getIndex())");
333+
writer.beginControlFlow("if (!linkedObject.isValid())");
334+
writer.emitStatement("throw new IllegalArgumentException(\"Each element of 'value' must be an valid managed object.\")");
335+
writer.endControlFlow();
336+
writer.emitStatement("links.add(linkedObject.row.getIndex())");
331337
writer.endControlFlow();
332338
writer.endMethod();
333339
} else {

realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ public void setColumnObject(AllTypes value) {
211211
row.nullifyLink(columnInfo.columnObjectIndex);
212212
return;
213213
}
214+
if (!value.isValid()) {
215+
throw new IllegalArgumentException("'value' is not a valid managed object.");
216+
}
214217
row.setLink(columnInfo.columnObjectIndex, value.row.getIndex());
215218
}
216219

@@ -242,6 +245,9 @@ public void setColumnRealmList(RealmList<AllTypes> value) {
242245
return;
243246
}
244247
for (RealmObject linkedObject : (RealmList<? extends RealmObject>) value) {
248+
if (!linkedObject.isValid()) {
249+
throw new IllegalArgumentException("Each element of 'value' must be an valid managed object.");
250+
}
245251
links.add(linkedObject.row.getIndex());
246252
}
247253
}

realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,9 @@ public void setFieldObjectNull(NullTypes value) {
522522
row.nullifyLink(columnInfo.fieldObjectNullIndex);
523523
return;
524524
}
525+
if (!value.isValid()) {
526+
throw new IllegalArgumentException("'value' is not a valid managed object.");
527+
}
525528
row.setLink(columnInfo.fieldObjectNullIndex, value.row.getIndex());
526529
}
527530

realm/realm-library/src/androidTest/java/io/realm/RealmObjectTest.java

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,135 @@ public void testSetNullLink() {
438438
assertNull(objA.getObject());
439439
}
440440

441+
public void testSetStandaloneObjectToLink() {
442+
CyclicType standalone = new CyclicType();
443+
444+
testRealm.beginTransaction();
445+
try {
446+
CyclicType target = testRealm.createObject(CyclicType.class);
447+
448+
try {
449+
target.setObject(standalone);
450+
fail();
451+
} catch (IllegalArgumentException ignored) {
452+
}
453+
} finally {
454+
testRealm.cancelTransaction();
455+
}
456+
}
457+
458+
public void testSetRemovedObjectToLink() {
459+
testRealm.beginTransaction();
460+
try {
461+
CyclicType target = testRealm.createObject(CyclicType.class);
462+
463+
CyclicType removed = testRealm.createObject(CyclicType.class);
464+
removed.removeFromRealm();
465+
466+
try {
467+
target.setObject(removed);
468+
fail();
469+
} catch (IllegalArgumentException ignored) {
470+
}
471+
} finally {
472+
testRealm.cancelTransaction();
473+
}
474+
}
475+
476+
public void testSetClosedObjectToLink() {
477+
testRealm.beginTransaction();
478+
CyclicType closed = testRealm.createObject(CyclicType.class);
479+
testRealm.commitTransaction();
480+
testRealm.close();
481+
assertTrue(testRealm.isClosed());
482+
483+
testRealm = Realm.getInstance(realmConfig);
484+
testRealm.beginTransaction();
485+
try {
486+
CyclicType target = testRealm.createObject(CyclicType.class);
487+
488+
try {
489+
target.setObject(closed);
490+
fail();
491+
} catch (IllegalArgumentException ignored) {
492+
}
493+
} finally {
494+
testRealm.cancelTransaction();
495+
}
496+
}
497+
498+
public void testSetStandaloneObjectToLinkLists() {
499+
CyclicType standalone = new CyclicType();
500+
501+
testRealm.beginTransaction();
502+
try {
503+
CyclicType target = testRealm.createObject(CyclicType.class);
504+
505+
RealmList<CyclicType> list = new RealmList<>();
506+
list.add(testRealm.createObject(CyclicType.class));
507+
list.add(standalone);
508+
list.add(testRealm.createObject(CyclicType.class));
509+
510+
try {
511+
target.setObjects(list);
512+
fail();
513+
} catch (IllegalArgumentException ignored) {
514+
}
515+
} finally {
516+
testRealm.cancelTransaction();
517+
}
518+
}
519+
520+
public void testSetRemovedObjectToLinkLists() {
521+
testRealm.beginTransaction();
522+
try {
523+
CyclicType target = testRealm.createObject(CyclicType.class);
524+
525+
CyclicType removed = testRealm.createObject(CyclicType.class);
526+
removed.removeFromRealm();
527+
528+
RealmList<CyclicType> list = new RealmList<>();
529+
list.add(testRealm.createObject(CyclicType.class));
530+
list.add(removed);
531+
list.add(testRealm.createObject(CyclicType.class));
532+
533+
try {
534+
target.setObjects(list);
535+
fail();
536+
} catch (IllegalArgumentException ignored) {
537+
}
538+
} finally {
539+
testRealm.cancelTransaction();
540+
}
541+
}
542+
543+
public void testSetClosedObjectToLinkLists() {
544+
testRealm.beginTransaction();
545+
CyclicType closed = testRealm.createObject(CyclicType.class);
546+
testRealm.commitTransaction();
547+
testRealm.close();
548+
assertTrue(testRealm.isClosed());
549+
550+
testRealm = Realm.getInstance(realmConfig);
551+
testRealm.beginTransaction();
552+
try {
553+
CyclicType target = testRealm.createObject(CyclicType.class);
554+
555+
RealmList<CyclicType> list = new RealmList<>();
556+
list.add(testRealm.createObject(CyclicType.class));
557+
list.add(closed);
558+
list.add(testRealm.createObject(CyclicType.class));
559+
560+
try {
561+
target.setObjects(list);
562+
fail();
563+
} catch (IllegalArgumentException ignored) {
564+
}
565+
} finally {
566+
testRealm.cancelTransaction();
567+
}
568+
}
569+
441570
public void testThreadModelClass() {
442571
// The model class' name (Thread) clashed with a common Java class.
443572
// The annotation process must be able to handle that.

0 commit comments

Comments
 (0)