JAL-2405 additional checks for circular reference in context or dataset
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 31 Mar 2017 11:26:45 +0000 (12:26 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 31 Mar 2017 11:26:45 +0000 (12:26 +0100)
src/jalview/datamodel/Alignment.java
src/jalview/datamodel/SequenceGroup.java
test/jalview/datamodel/AlignmentTest.java
test/jalview/datamodel/SequenceGroupTest.java

index 41488ea..2dafc0c 100755 (executable)
@@ -1011,6 +1011,10 @@ public class Alignment implements AlignmentI
     }
     else if (dataset == null && data != null)
     {
+      if (data == this)
+      {
+        throw new IllegalArgumentException("Circular dataset reference");
+      }
       if (!(data instanceof Alignment))
       {
         throw new Error(
index e37c55e..1246d23 100755 (executable)
@@ -1358,7 +1358,7 @@ public class SequenceGroup implements AnnotatedCollectionI
     AnnotatedCollectionI ref = ctx;
     while (ref != null)
     {
-      if (ref == this)
+      if (ref == this || ref.getContext() == ctx)
       {
         throw new IllegalArgumentException(
                 "Circular reference in SequenceGroup.context");
index 68933bd..c5d09c1 100644 (file)
@@ -1260,4 +1260,13 @@ public class AlignmentTest
     assertEquals(a.getHiddenSequences().getSize(), 1);
   }
 
+  @Test(
+    groups = "Functional",
+    expectedExceptions = { IllegalArgumentException.class })
+  public void testSetDataset_selfReference()
+  {
+    SequenceI seq = new Sequence("a", "a");
+    AlignmentI alignment = new Alignment(new SequenceI[] { seq });
+    alignment.setDataset(alignment);
+  }
 }
index 65549f2..6e1c2db 100644 (file)
@@ -10,6 +10,8 @@ import static org.testng.Assert.fail;
 
 import jalview.schemes.NucleotideColourScheme;
 
+import junit.extensions.PA;
+
 import org.testng.annotations.Test;
 
 public class SequenceGroupTest
@@ -111,6 +113,21 @@ public class SequenceGroupTest
       // expected
       assertNull(sg3.getContext());
     }
+
+    /*
+     * use PrivilegedAccessor to 'force' a SequenceGroup with
+     * a circular context reference
+     */
+    PA.setValue(sg2, "context", sg2);
+    try
+    {
+      sg3.setContext(sg2); // circular reference in sg2
+      fail("Expected exception");
+    } catch (IllegalArgumentException e)
+    {
+      // expected
+      assertNull(sg3.getContext());
+    }
   }
 
   @Test(groups = { "Functional" })