Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@

public class StationTessellatorImpl implements StationTessellator {

// Hard ceiling on the int-buffer size so it can never grow large enough for
// bufferSize * 4 (the byte-buffer allocation) to overflow a signed int.
// 2^28 ints = 1 GiB direct buffer, far beyond anything vanilla rendering needs;
// the buffer base size is 2^21 ints, so this still allows several doublings.
private static final int MAX_BUFFER_SIZE = 1 << 28;

private final Tessellator self;
private final TessellatorAccessor access;
private final int[] fastVertexData = new int[32];
Expand Down Expand Up @@ -103,11 +109,19 @@ public void quad(BakedQuad quad, float x, float y, float z, int colour0, int col

@Override
public void ensureBufferCapacity(int criticalCapacity) {
if (access.stationapi$getBufferPosition() >= access.stationapi$getBufferSize() - criticalCapacity) {
LOGGER.info("Tessellator is nearing its maximum capacity. Increasing the buffer size from {} to {}", access.stationapi$getBufferSize(), access.stationapi$getBufferSize() * 2);
access.stationapi$setBufferSize(access.stationapi$getBufferSize() * 2);
access.stationapi$setBuffer(Arrays.copyOf(access.stationapi$getBuffer(), access.stationapi$getBufferSize()));
ByteBuffer newBuffer = GlAllocationUtils.allocateByteBuffer(access.stationapi$getBufferSize() * 4);
int bufferSize = access.stationapi$getBufferSize();
if (access.stationapi$getBufferPosition() >= bufferSize - criticalCapacity) {
if (bufferSize >= MAX_BUFFER_SIZE) {
// Already at the ceiling; doubling further would overflow bufferSize * 4.
// Leave the buffer as-is rather than allocating an invalid (negative) capacity.
return;
}
int newBufferSize = Math.min(bufferSize * 2, MAX_BUFFER_SIZE);
LOGGER.info("Tessellator is nearing its maximum capacity. Increasing the buffer size from {} to {}", bufferSize, newBufferSize);
access.stationapi$setBufferSize(newBufferSize);
access.stationapi$setBuffer(Arrays.copyOf(access.stationapi$getBuffer(), newBufferSize));
// long arithmetic so the byte count can never overflow a signed int.
ByteBuffer newBuffer = GlAllocationUtils.allocateByteBuffer((int) ((long) newBufferSize * 4));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how long helps here if it's casted to int immediately after. Plus, isn't everything that's calculated before prevents newBufferSize * 4 from ever overflowing in the first place?

access.stationapi$setByteBuffer(newBuffer);
access.stationapi$setIntBuffer(newBuffer.asIntBuffer());
access.stationapi$setFloatBuffer(newBuffer.asFloatBuffer());
Expand Down