fix: bind VBlob data views to their arena - #236
Merged
Conversation
lopcode
enabled auto-merge (squash)
September 10, 2026 06:39
Owner
|
Thank you for your contribution, and for including tests for validation. I realised there were a couple of other places with the same bug, so I included them in this PR. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This fixes the arena lifetime and thread-access guarantees of buffers returned by
VBlob.asArenaScopedByteBuffer().getUnsafeDataAddress()currently usesasSlice()to set the bounds of the pointer returned byvips_blob_get(). The pointer retains its global scope, so the returned buffer's scope remains alive after the owning arena closes and releases the native memory. Buffers created withArena.ofConfined()also appear accessible from other threads.The following reproduces the lifetime mismatch without reading freed memory:
Changes
reinterpret(length, arena, null)to bind the data view to the blob's arena and set its bounds. This preserves the existing cleanup ownership without copying data or registering another deallocator.VBlobByteBufferSampleso the existing sample CI also catches the regression. The native tests live inintegrationTest, keeping the default unit tests runnable before libvips is installed.Validation
Tested against base commit
1ed5dd596fb48ab8c7b69b21a28f05fc3090851eon Linux ARM64 with Temurin 25, libvips 8.18.6, and JUnit Platform Console 1.11.3.javac --release 22, then ran the six new tests and the existingSenseCheckTest: 2/7 passed and 5/7 failed before the fix; 7/7 passed after it.VBlobByteBufferSamplefails its scope assertion before the fix and passes afterward.git diff --checkpasses. I have not run the full Gradle build or tested other OS/JDK combinations locally.With the project's toolchain and libvips installed, the new regression tests can be run with:
Compatibility
This enforces the documented arena lifetime contract; it does not reduce native allocations or change when native memory is released. Code that previously accessed a confined arena's buffer from another thread will now be subject to the arena's thread-access checks. Such callers should use a shared arena or an independent copy.