Skip to content

Fix remaining audit compatibility defects - #25

Merged
Project516 merged 12 commits into
masterfrom
p516/audit-compatibility
Nov 3, 2026
Merged

Project516 merged 12 commits into
masterfrom
p516/audit-compatibility

Conversation

@Project516

@Project516 Project516 commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

Several VM and native operations diverge from HotSpot: failed bootstraps run again, exception handlers can catch unrelated same-named classes, and open-file attributes can describe the wrong file after unlink. Fix these paths and the other confirmed audit defects in their shared implementations.

  • Cache failed invokedynamic linkage and share resolved dynamic constants between ldc and bootstrap arguments, including primitive constants.
  • Resolve exception catch types through the defining loader, allowing loading to suspend without re-executing the throwing instruction. A failed catch-type load restarts dispatch at that handler's bytecode position. Cover interpreted, compiled and hidden classes.
  • Apply and report host POSIX permissions, preserving host errno and the existing no-op for virtual backends without permission bits. Preserve descriptor size, mode and inode identity after rename/unlink, and return the native error for invalid descriptors.
  • Follow host symlinks before .. for reads and mutations, preserving terminal symlinks and virtual mount selection.
  • Reject dictionaries while a wrapped deflater is active, preserving zero-length output, finish and reset behavior.
  • Exclude private static methods from overload selection while preserving the package-private and protected helpers used by native callbacks.

Validation: failing-before/passing-after HotSpot comparisons for the confirmed defects; DeflaterState, ZipStreams, LinkageCaching, LoaderCatch, FstatAfterUnlink, OpenFileInodes, PosixPermissions, and host symlink operations pass. The native-callback, library and JS-proxy suites, VFS regressions and TypeScript typecheck pass. CI also runs the new permission-error, catch-resolution-failure and reference-exit regressions, plus broader verification.

Additional review at a28620f covered the files skipped by the review bot: test/paths/SymlinkDotDot.java and the full test/programs.test.ts diff. No findings. Coverage included read/create/move/delete paths, terminal-symlink target preservation, the reference exit assertion, temporary-file cleanup, Windows skip, and ONLY / test-name selection.

Noticed, not fixed

The support docs now state the existing stored-block compression limitation and explain why browser fetch cannot expose manual redirects. Java long results keep the established JS-number conversion; the browser guide documents its precision limit and exact string/array alternatives.

@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Summary

Summary by CodeRabbit

  • New Features
    • Filesystem metadata now includes permission bits, and file descriptors retain correct inode and attribute information after files are renamed or removed.
    • Path resolution better reflects symlinks and .. segments on supported host filesystems.
    • File permission changes now report errors for missing files, invalid descriptors, and read-only filesystems.
  • Bug Fixes
    • Static and instance method lookups now consistently expose only public methods.
    • Improved handling of Java exceptions, dynamic constants, and linkage failures.
    • Deflater now handles empty output buffers and dictionary updates more consistently.
  • Documentation
    • Clarified Java long conversions, compression behavior, and browser redirect handling.

This pull request updates filesystem path resolution and POSIX file metadata, JVM linkage and exception handling, Java library method visibility, and Deflater behavior. It also adds regression tests and updates browser and runtime documentation.

Changes: Filesystem path resolution

Layer / File(s) Summary
Backend path resolution
src/fs.ts, src/node.ts, src/natives/io.ts, test/fs.test.ts, test/paths/SymlinkDotDot.java, test/programs.test.ts
VFS.resolvePath delegates eligible paths to a backend resolver. NodeBackend resolves paths for the root backend, and tests compare symlink paths containing .. with HotSpot behavior.

POSIX metadata and open files

Layer / File(s) Summary
File metadata and shared inode tracking
src/fs.ts, src/node.ts, src/natives/io.ts, src/natives/nio.ts
Stat includes mode bits, and host stat reports them. File operations and NIO use shared inode tracking for attributes and file keys.
Detached file operations and permissions
src/natives/io.ts, src/natives/nio.ts, test/java/FstatAfterUnlink.java, test/java/PosixPermissions.java
Rename and removal preserve metadata for affected open files. NIO reports detached-file attributes and implements chmod0 and fchmod0; Java tests cover permissions and file descriptors after unlink.

JVM linkage and exception handling

Layer / File(s) Summary
Dynamic constant and call-site caching
src/indy.ts, src/jvm.ts, src/jit.ts, test/java/LinkageCaching.java
Dynamic constants use the constant-pool cache. Linkage failures of type LinkageError are cached, and JIT execution falls back for cached PendingThrow sites.
Catch-class resolution
src/interp.ts, src/jit.ts, test/java/LoaderCatch.java
Exception handling resolves unloaded catch classes through a native frame. Tests exercise catch behavior across class-loader boundaries.

Library method visibility

Layer / File(s) Summary
Public method lookup
src/library.ts, test/library/Lib.java, test/library.test.ts, docs/browser.md
Static and instance method lookup excludes non-public methods. Tests cover static overload selection and hidden methods; documentation describes public method exposure.

Deflater behavior

Layer / File(s) Summary
Deflater state handling
src/natives/zip.ts, test/java/DeflaterState.java, docs/support.md
Deflater rejects dictionary changes after wrapped output begins and returns immediately for an empty output buffer. The documentation describes its output and compression behavior.

Browser interoperability documentation

Layer / File(s) Summary
Numeric conversion and HTTP behavior
docs/browser.md, docs/support.md
The documentation describes Java long conversion and precision limits, as well as browser fetch redirect handling and complete response-body reads.

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Bug fix

Possibly related PRs

  • Project516/java-web#8: Adds the Backend.chmod contract and host permission changes, which connect to this pull request’s filesystem permission updates.
Merge Risk: Moderate · up to acc62

Setting file permissions on a writable in-memory mount, or after a host chmod failure, can now fail with a read-only-filesystem error where it previously succeeded silently. Fix the error mapping before merging. The symlink HotSpot comparison test should also assert that the reference run succeeds.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 17.39% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly summarizes the pull request’s main purpose: fixing remaining compatibility defects identified by the audit.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The pull request description directly covers the VM, native filesystem, symlink, deflater, library, documentation, and test changes in the changeset.
Full details: Docstring Coverage

Explanation

Docstring coverage is 17.39% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 23 functions across 20 files. (2 skipped: 2 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Simplify code
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

I’m a rabbit checking files by moonlit light,
I follow each link where .. turns right.
Long values hop past numbers’ safe fence,
Cached calls remember their last consequence.
I nibble stored blocks, then bound away,
With open-file metadata tucked safe for the day.

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.
Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 2590a748-2b55-436b-80fd-800220e14a14
Commits

Reviewing files that changed from the base of the PR and between 608479d and acc624b.

Files selected for processing: 22
  • docs/browser.md
  • docs/support.md
  • src/fs.ts
  • src/indy.ts
  • src/interp.ts
  • src/jit.ts
  • src/jvm.ts
  • src/library.ts
  • src/natives/io.ts
  • src/natives/nio.ts
  • src/natives/zip.ts
  • src/node.ts
  • test/fs.test.ts
  • test/java/DeflaterState.java
  • test/java/FstatAfterUnlink.java
  • test/java/LinkageCaching.java
  • test/java/LoaderCatch.java
  • test/java/PosixPermissions.java
  • test/library.test.ts
  • test/library/Lib.java
  • test/paths/SymlinkDotDot.java
  • test/programs.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Recent review details
Context from checks skipped due to timeout: 6
  • GitHub Check: jtreg / run (3)
  • GitHub Check: jtreg / run (1)
  • GitHub Check: jtreg / run (4)
  • GitHub Check: jtreg / run (2)
  • GitHub Check: CodeRabbit
  • GitHub Check: test
Additional context used
Learnings: 2
Learning: 2026-11-01T20:52:55.551Z
Learnt from: CR
Repo: Project516/java-web PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-11-01T20:52:55.551Z
Learning: Source excerpt:
# java-web

## Direction

- Prove it with tests: programs whose output must match HotSpot exactly, and
  OpenJDK's own regression tests where they can run.

Applied to files:

  • test/programs.test.ts
Learning: 2026-11-01T20:52:55.551Z
Learnt from: CR
Repo: Project516/java-web PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-11-01T20:52:55.551Z
Learning: Source excerpt:
# java-web

## Direction

- Compatibility first. Run JDK classes unmodified and implement what HotSpot
  does for them (natives, VM upcalls, init order). Do not patch or replace JDK
  classes. When behavior differs from HotSpot, HotSpot is right.

Applied to files:

  • src/jvm.ts
ast-grep (0.51.1)
test/java/PosixPermissions.java

[warning] 14-14: Temporary file not deleted
Context: Files.createTempFile("java-web-mode", ".tmp")
Note: [CWE-377] Insecure Temporary File. Security best practice.

(tempfile-delete)

test/java/FstatAfterUnlink.java

[warning] 25-25: Temporary file not deleted
Context: Files.createTempFile("fstat-unlink", ".tmp")
Note: [CWE-377] Insecure Temporary File. Security best practice.

(tempfile-delete)

PMD (7.28.0)
test/library/Lib.java

[Medium] 4-4: UnusedPrivateMethod (Best Practices): Avoid unused private methods such as 'visible(String)'.

(UnusedPrivateMethod (Best Practices))

[Medium] 5-5: UnusedPrivateMethod (Best Practices): Avoid unused private methods such as 'hidden()'.

(UnusedPrivateMethod (Best Practices))

test/java/PosixPermissions.java

[Medium] 24-24: AvoidUsingOctalValues (Error Prone): Avoid integer literals that start with zero (interpreted as octal), remove the leading 0 to get a decimal literal (or use explicit 0x, 0b prefixes)

(AvoidUsingOctalValues (Error Prone))

[Medium] 28-28: AvoidUsingOctalValues (Error Prone): Avoid integer literals that start with zero (interpreted as octal), remove the leading 0 to get a decimal literal (or use explicit 0x, 0b prefixes)

(AvoidUsingOctalValues (Error Prone))

test/java/FstatAfterUnlink.java

[Medium] 40-40: AvoidUsingOctalValues (Error Prone): Avoid integer literals that start with zero (interpreted as octal), remove the leading 0 to get a decimal literal (or use explicit 0x, 0b prefixes)

(AvoidUsingOctalValues (Error Prone))

[Medium] 48-48: AvoidUsingOctalValues (Error Prone): Avoid integer literals that start with zero (interpreted as octal), remove the leading 0 to get a decimal literal (or use explicit 0x, 0b prefixes)

(AvoidUsingOctalValues (Error Prone))

[Medium] 63-63: PreserveStackTrace (Best Practices): Thrown exception does not preserve the stack trace of exception 'e' on all code paths

(PreserveStackTrace (Best Practices))

Additional comments: 15
src/library.ts: 1

503-503: LGTM!

test/library/Lib.java: 1

3-5: LGTM!

test/library.test.ts: 1

55-59: LGTM!

docs/browser.md: 1

72-72: LGTM!

Also applies to: 76-80

src/indy.ts: 1

468-472: LGTM!

Also applies to: 476-481

src/jvm.ts: 1

457-457: LGTM!

Also applies to: 460-472

src/jit.ts: 1

608-608: LGTM!

Also applies to: 888-888

test/java/LinkageCaching.java: 1

1-126: LGTM!

src/interp.ts: 1

624-627: LGTM!

Also applies to: 639-656, 658-689

test/java/LoaderCatch.java: 1

1-83: LGTM!

src/natives/nio.ts: 3

5-9: LGTM!

53-71: LGTM!

106-109: Functional Correctness

The detached inode alias concern is not present.

Although openFile does not initially set ino, removePath calls detachFile first, and detachFile stores the inode before the path entry is deleted. The detached fstat0 path therefore uses the stored inode. Assigning ino inside openFile is not required for this case.

test/java/FstatAfterUnlink.java: 1

1-68: LGTM!

test/java/PosixPermissions.java: 1

1-42: LGTM!

@project516-review-bot project516-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This PR fixes multiple HotSpot audit compatibility defects: invokedynamic bootstrap caching (including failed bootstraps and primitive dynamic constants), exception catch type resolution through defining loaders, file inode/permission preservation after rename/unlink, host symlink resolution before '..', Deflater dictionary rejection during active compression, and library call restriction to public methods. Tests validate each fix against HotSpot behavior. However, the exception handler resolution in src/interp.ts has a defect: when catch type resolution fails (e.g., NoClassDefFoundError), the code catches the error and continues to subsequent handlers instead of throwing immediately, violating the JVM spec which requires the linkage error to be thrown at the point of the failing catch clause.


review-bot, model nvidia/nemotron-3-ultra-550b-a55b:free, verdict request_changes

Comment thread src/interp.ts Resolved

@coderabbitai coderabbitai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

  • Fix comments: Fix CodeRabbit comments on this PR

Comment thread src/natives/nio.ts Resolved
Comment thread test/programs.test.ts Resolved

@project516-review-bot project516-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This PR fixes several audit compatibility defects: invokedynamic linkage caching, exception catch type resolution, file inode/permission preservation after unlink/rename, host symlink resolution before '..', Deflater dictionary rejection, and private static method exclusion. However, there are clear defects in the exception handling logic (interp.ts), primitive dynamic constant caching (indy.ts), NodeBackend symlink resolution for non-root mounts (node.ts), and unsafe Map iteration during rename (io.ts).

Not approved: 1 earlier point is still open in the threads.


review-bot, model nvidia/nemotron-3-ultra-550b-a55b:free, verdict comment

Comment thread src/interp.ts Resolved
Comment thread src/natives/io.ts Resolved

@project516-review-bot project516-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This PR fixes multiple audit compatibility defects: invokedynamic linkage caching for failed bootstraps and primitive dynamic constants; exception catch-type resolution through defining loader with restart-on-failure semantics; POSIX permission reporting with host errno preservation; inode identity preservation after rename/unlink; symlink resolution before '..' components; Deflater dictionary rejection during active compression; and private static method exclusion from JS overload selection. A clear bug exists in src/natives/io.ts where a Map is modified during keys() iteration. The exception handler restart logic in src/interp.ts was flagged in earlier review as diverging from JVM spec (restarts from handler 0 instead of failing handler), though PR claims HotSpot parity.

Not approved: the diff of test/paths/SymlinkDotDot.java, test/programs.test.ts was too large to read.


review-bot, model nvidia/nemotron-3-ultra-550b-a55b:free, verdict comment

Comment thread src/natives/io.ts Resolved
@project516-review-bot
project516-review-bot Bot dismissed their stale review November 3, 2026 14:54

Superseded by the review of a28620f, which has no blocking findings, and its threads are settled.

@Project516
Project516 merged commit 242471c into master Nov 3, 2026
12 checks passed
@Project516
Project516 deleted the p516/audit-compatibility branch November 3, 2026 15:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant