# HG changeset patch # User Laurens Holst # Date 1659969397 -7200 # Mon Aug 08 16:36:37 2022 +0200 # Node ID 1b4e65914aae57a198628353b2275e84e34674d8 # Parent ebd4102a52fe6162746e795f3aeee0e344290a84 Scope: Fix serialising symbols with a cycle in them. Now it does not recur once it finds a cycle. Thanks to inchl for the report. diff --git a/src/main/java/nl/grauw/glass/Scope.java b/src/main/java/nl/grauw/glass/Scope.java --- a/src/main/java/nl/grauw/glass/Scope.java +++ b/src/main/java/nl/grauw/glass/Scope.java @@ -124,10 +124,10 @@ } public String serializeSymbols() { - return serializeSymbols(""); + return serializeSymbols("", new SingleLinkedList(this, null)); } - public String serializeSymbols(String namePrefix) { + public String serializeSymbols(String namePrefix, SingleLinkedList breadcrumbs) { StringBuilder builder = new StringBuilder(); TreeMap sortedMap = new TreeMap<>(symbols); for (Map.Entry entry : sortedMap.entrySet()) { @@ -143,7 +143,9 @@ if (value.is(Type.CONTEXT)) { try { Scope context = (Scope)value.getContext(); - builder.append(context.serializeSymbols(name + ".")); + if (!breadcrumbs.contains(context)) { + builder.append(context.serializeSymbols(name + ".", new SingleLinkedList(context, breadcrumbs))); + } } catch (EvaluationException e) { // ignore } @@ -156,4 +158,16 @@ return serializeSymbols(); } + private static class SingleLinkedList { + private T head; + private SingleLinkedList tail; + public SingleLinkedList(T head, SingleLinkedList tail) { + this.head = head; + this.tail = tail; + } + public boolean contains(T value) { + return value == head || (tail != null && tail.contains(value)); + } + } + } diff --git a/src/test/java/nl/grauw/glass/SymbolsTest.java b/src/test/java/nl/grauw/glass/SymbolsTest.java --- a/src/test/java/nl/grauw/glass/SymbolsTest.java +++ b/src/test/java/nl/grauw/glass/SymbolsTest.java @@ -210,6 +210,26 @@ ); } + @Test + public void testCycle() { + assertIterableEquals( + s( + "Test: equ 1H", + "Test.x: equ 7H", + "Test.y: equ 1H", + "Test.z: equ 2H" + ), + symbols( + " nop", + "Test: PROC", + "x: equ 7", + "y: equ Test", + " nop", + "z: ENDP" + ) + ); + } + @TempDir static Path temporaryDirectory;