Skip to content

Commit 612f1e4

Browse files
committed
Avoid theoretical stack overflow in Ranges.returnId
1 parent 2eb2d71 commit 612f1e4

File tree

1 file changed

+50
-41
lines changed
  • src/main/java/com/hivemq/client/internal/util

1 file changed

+50
-41
lines changed

src/main/java/com/hivemq/client/internal/util/Ranges.java

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,59 @@ public Ranges(final int minId, final int maxId) {
3434
}
3535

3636
public int getId() {
37-
return rootRange.getId();
37+
if (rootRange.start == rootRange.end) {
38+
return -1;
39+
}
40+
final int id = rootRange.start;
41+
rootRange.start++;
42+
if ((rootRange.start == rootRange.end) && (rootRange.next != null)) {
43+
rootRange = rootRange.next;
44+
}
45+
return id;
3846
}
3947

4048
public void returnId(final int id) {
41-
rootRange = rootRange.returnId(id);
49+
Range current = rootRange;
50+
if (id < current.start - 1) {
51+
rootRange = new Range(id, id + 1, current);
52+
return;
53+
}
54+
Range prev = current;
55+
current = returnId(current, id);
56+
while (current != null) {
57+
if (id < current.start - 1) {
58+
prev.next = new Range(id, id + 1, current);
59+
return;
60+
}
61+
prev = current;
62+
current = returnId(current, id);
63+
}
64+
}
65+
66+
private @Nullable Range returnId(final @NotNull Range range, final int id) {
67+
final Range next = range.next;
68+
if (id == range.start - 1) {
69+
range.start = id;
70+
return null;
71+
}
72+
if (id < range.end) {
73+
throw new IllegalStateException("The id was already returned. This must not happen and is a bug.");
74+
}
75+
if (id == range.end) {
76+
if (next == null) {
77+
throw new IllegalStateException("The id is greater than maxId. This must not happen and is a bug.");
78+
}
79+
range.end++;
80+
if (range.end == next.start) {
81+
range.end = next.end;
82+
range.next = next.next;
83+
}
84+
return null;
85+
}
86+
if (next == null) {
87+
throw new IllegalStateException("The id is greater than maxId. This must not happen and is a bug.");
88+
}
89+
return next;
4290
}
4391

4492
public int resize(final int maxId) {
@@ -82,44 +130,5 @@ private static class Range {
82130
this.end = end;
83131
this.next = next;
84132
}
85-
86-
int getId() {
87-
if (start == end) {
88-
return -1;
89-
}
90-
final int id = this.start;
91-
start++;
92-
if ((start == end) && (next != null)) {
93-
start = next.start;
94-
end = next.end;
95-
next = next.next;
96-
}
97-
return id;
98-
}
99-
100-
@NotNull Range returnId(final int id) {
101-
Range range = this;
102-
if (id < start - 1) {
103-
range = new Range(id, id + 1, this);
104-
} else if (id == start - 1) {
105-
start--;
106-
} else if (id < end) {
107-
throw new IllegalStateException("The id was already returned. This must not happen and is a bug.");
108-
} else if (id == end) {
109-
if (next == null) {
110-
throw new IllegalStateException("The id is greater than maxId. This must not happen and is a bug.");
111-
}
112-
end++;
113-
if (end == next.start) {
114-
end = next.end;
115-
next = next.next;
116-
}
117-
} else if (next != null) {
118-
next = next.returnId(id);
119-
} else {
120-
throw new IllegalStateException("The id is greater than maxId. This must not happen and is a bug.");
121-
}
122-
return range;
123-
}
124133
}
125134
}

0 commit comments

Comments
 (0)