dependabot[bot] opened a new pull request, #25686: URL: https://github.com/apache/camel/pull/25686
Bumps [io.github.classgraph:classgraph](https://github.com/classgraph/classgraph) from 4.8.189 to 4.8.193. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/classgraph/classgraph/releases">io.github.classgraph:classgraph's releases</a>.</em></p> <blockquote> <h2>ClassGraph 4.8.193</h2> <p><strong>ClassGraph 5.0.0 is coming shortly</strong>, and requires JDK 17 or newer. 4.8.193 is a bugfix release on the 4.x maintenance branch, and continues the file-by-file audit of the codebase that produced 4.8.190 through 4.8.192. As before, the bugs listed here were found by Claude through careful code analysis, and were fixed on the v5 branch and backported to v4.</p> <p>The largest group this time came from an audit of what a scan holds open and when it lets go of it: memory mappings, file handles, streams and pooled objects.</p> <h2>Bug fixes: memory mapping</h2> <ul> <li> <p><strong>Closing a <code>ScanResult</code> could unmap a file while another thread was still reading it, killing the JVM.</strong> <code>FileSlice#close()</code> unmapped the file the slice was reading, but aliases of that mapping escape three ways: a <code>RandomAccessByteBufferReader</code> keeps a duplicate for the life of the reader, <code>FileSlice#read()</code> hands a slice of the mapping to the caller, and a sub-slice duplicated it. Below JDK 22 the only way to unmap on demand is <code>Unsafe::invokeCleaner</code>, which frees the address range immediately and unconditionally, so a thread that read one byte afterwards took a SIGSEGV. A sub-slice now reads through the toplevel slice instead of duplicating the mapping, a reader taken before the close is given the slice's closed flag to check before each read, and a file is unmapped only once the toplevel slice has closed and every view of the mapping that a caller could still read has been released.</p> </li> <li> <p><strong>A memory-mapped jarfile stayed mapped after the scan that mapped it was closed.</strong> Below JDK 22 there is no arena, so closing a <code>ScanResult</code> merely dropped the last reference to each mapping and left the unmapping to the garbage collector — which might do it minutes later, or never. Windows refuses to delete, rename or overwrite a file while it is mapped, so a scanned jar stayed locked long after the <code>ScanResult</code> was closed, an extracted temporary file was left behind, and a scanned directory could not be deleted. Mappings are now unmapped explicitly when the scan closes, on every JDK: with the arena on JDK 22 and later, with <code>Unsafe::invokeCleaner</code> on JDK 9 to 21, and with <code>sun.misc.Cleaner</code> below JDK 9. The garbage collector is now only the fallback, for a mapping that could not be unmapped explicitly.</p> </li> <li> <p><strong>A closed resource stream went on holding its reader</strong>, and a reader of a memory-mapped file holds a view of the mapping, so the file stayed mapped for as long as anything still referred to the stream. The stream now drops its reader as it closes.</p> </li> <li> <p><strong><code>enableMemoryMapping()</code> still maps on every JDK.</strong> The obvious way to close the crash above would have been to stop mapping below JDK 22, where the unmapping cannot be made safe by the arena — but that would have given up the mapping speedup (16-38% faster than the <code>RandomAccessFile</code> API on Windows) on every release but the newest. Ordering the unmapping behind the last live view of the mapping makes it safe without that, so mapping still happens wherever it is asked for.</p> </li> </ul> <h2>Bug fixes: resource and scan lifecycle</h2> <ul> <li> <p><strong>A failed scan leaked every file handle, memory mapping and module reader it had opened.</strong> On the failure path the <code>NestedJarHandler</code> was closed only when there was no <code>FailureHandler</code>, or when the <code>FailureHandler</code> itself threw; a <code>FailureHandler</code> that returned normally fell through to a step that deletes temporary files but closes nothing. Three sibling leaks were fixed with it: the <code>Scanner</code> constructor released the handler only on <code>InterruptedException</code>, so a throwing classpath element filter leaked the whole handler with no way for the caller to reach it; a <code>ScanResultProcessor</code> that threw an <code>Error</code> — which is what a failing assertion inside one throws — skipped both <code>close()</code> calls, and nothing else can close that <code>ScanResult</code>; and a <code>ScanResult</code> that was garbage collected without being closed left a dead <code>WeakReference</code> hus k in a static set forever, so the set grew without limit in a program that scans repeatedly without closing.</p> </li> <li> <p><strong>A resource that could not be opened was left marked as open.</strong> <code>Resource#checkCanOpen</code> set the open flag before checking whether the <code>ScanResult</code> had been closed, so every later attempt to open that resource reported "Resource is already open" instead of the real reason it could not be opened.</p> </li> <li> <p><strong>Handing a pooled object back after a <code>ScanResult</code> was closed either threw or leaked.</strong> Closing a <code>ScanResult</code> force-closes the inflater and module-reader recyclers, but a recycler kept no memory of that: it drained the pool and left <code>recycle()</code> free to add instances back in. An instance handed back afterwards was either rejected outright — with "Tried to recycle an instance that was not in use" thrown out of the <code>close()</code> that was handing it back — or, if it had been acquired after the force-close, pooled into a recycler that nothing would ever drain again, leaking the <code>Inflater</code> or <code>ModuleReader</code> it held. Closing a resource stream after closing the <code>ScanResult</code> reaches the first case. A force-close is now terminal.</p> </li> </ul> <h2>Bug fixes: zipfile reading</h2> <ul> <li> <p><strong>A zipfile comment containing the bytes <code>PK\x05\x06</code> made the jarfile unreadable.</strong> The end of central directory record is found by scanning back from the end of the file for that signature, and the record's comment length field was never checked against the bytes actually present, so the first plausible-looking signature found was accepted as the real record. The comment length now has to account for the remaining bytes exactly, and the scan continues to an earlier candidate if it does not. (Zipfiles do exist with data appended after the comment, or with the wrong comment length recorded, so if no candidate satisfies the check the last signature found is still used, as before.)</p> </li> <li> <p><strong>A jarfile whose entry names had been lower-cased was read as having no manifest at all</strong>, which silently dropped its <code>Class-Path</code>, its <code>Bundle-ClassPath</code> and everything else the manifest says. <code>java.util.zip.ZipFile</code> finds that manifest, because it matches <code>META-INF/</code> and <code>MANIFEST.MF</code> a character at a time with the case bit masked off. The manifest is now looked for under its canonical name first, and only then under a name that differs from it in case alone.</p> </li> <li> <p><strong>A classfile named <code>Foo.CLASS</code> aborted the entire scan.</strong> <code>JarUtils.classfilePathToClassName</code> threw for a path whose extension was not exactly <code>.class</code>, even though such a file declares the same class at the same position in the directory tree and can be read like any other. Every "is this a classfile" test now goes through one case-insensitive predicate. <code>module-info.class</code> and <code>package-info.class</code> stay case-sensitive, since the JLS and the JPMS mandate those exact names.</p> </li> </ul> <h2>Bug fixes: nested jar paths and classpath URLs</h2> <ul> <li> <p><strong>The nested jar separator is now spelled <code>!/</code> everywhere, as the <code>jar:</code> URL scheme requires.</strong> <code>sun.net.www.protocol.jar.Handler</code> looks for the first <code>!</code> that is immediately followed by <code>/</code>, and <code>java.net.JarURLConnection</code> rejects a URL whose <code>!</code> is not followed by <code>/</code> while the URL is being constructed. ClassGraph found the outermost separator by testing the filesystem and then took every later <code>!</code> to be a separator too — but <code>!</code> is a legal character in a file or entry name, so <code>outer.jar!/dir!name</code> was split inside <code>dir!name</code>, and normalizing <code>outer.jar!/dir!name/x.txt</code> produced a URL naming an entry that does not exist. Which <code>!</code> characters separate is now decided by how the outermost one is spelled, and <code>JarUtils#toJarUrlSeparators</code> is the single place a looser path is rewritten into the scheme's form.</p> </li> <li> <p><strong>A relative path that looks like a URL was misread as one.</strong> <code>:</code> is a legal filename character on every platform ClassGraph supports except Windows, and a relative path need not begin with <code>/</code>, so <code>foo:bar</code> is spelled exactly like a URL whose scheme is <code>foo</code>. The syntactic rule is now applied only after the filesystem has been asked, so <code>cgtest:relpath/dir!name/y.jar</code> is no longer split at the <code>!</code> while <code>reldir/dir!name/y.jar</code> — the same path but for the colon — is correctly left alone.</p> </li> <li> <p><strong>A URL scheme containing a digit was not recognized when ordering the classpath</strong>, even though RFC 3986 allows digits after the first character.</p> </li> <li> <p><strong>The same resource reached under two spellings was scanned twice.</strong> Two of these: a scheme that is merely kept rather than recognized by name, such as <code>S3://bucket/key</code>, was passed through in whatever case it was written in, rather than lowercased to its canonical form; and the key that decides whether two resources are the same file canonicalized only the directory the file is in, keeping the name it was reached by, so a jar reached through a symlink was a different file from the jar itself, and on a case-folding filesystem a jar named with a different case was a different file too — which on macOS and Windows the module path and the classpath routinely produce.</p> </li> <li> <p><strong>18 of the 20 <code>ClassLoaderHandler</code> registry entries had <code>null</code> cached for their package root prefixes.</strong> The registry entries are built by a static initializer that runs before the prefix constants declared further down the same class are assigned, and the entry read the prefixes in its constructor. The entry now forwards to the handler rather than caching, so it reads the constants after they are assigned. Fifteen of the affected handlers were unaffected in practice, since <code>null</code> is replaced by the defaults; the other three returned "no package root prefixes", and none of the three justified suppressing package roots — the JPMS handler in particular contributes the jarfiles a Java agent appended to the system classloader's search, which are not modules, so a Spring Boot jar appended that way needs its package root stripped like any other.</p> </li> <li> <p><strong>A failure to parse or convert a jar URL discarded the underlying cause</strong>, so the exception said what had failed but not why.</p> </li> </ul> <h2>Bug fixes: interruption handling</h2> <ul> <li> <p><strong>Interrupting a scan could leave it running to completion</strong>, returning a <code>ScanResult</code> that was silently missing a classpath element. The catch-all that turns a failed classpath entry into a log line and moves on also caught <code>InterruptedException</code> — and that exception arrives with the interrupt status already cleared when it comes out of waiting for a classpath element another work unit is already opening, so nothing downstream noticed either.</p> </li> <li> <p><strong>A cancelled scan was reported as a failed one.</strong> <code>Future.get()</code> wraps an <code>InterruptedException</code> thrown by a worker in an <code>ExecutionException</code> like any other, and both places that catch that handed it straight to the "record an exception" path, which is checked ahead of the interruption check. It also cost a genuine failure its report, since only the first exception is kept. An interrupted worker is now recorded as an interruption.</p> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/classgraph/classgraph/commit/f7b9842c1014da42af1ebd3c12f32683f940157b"><code>f7b9842</code></a> [maven-release-plugin] prepare release classgraph-4.8.193</li> <li><a href="https://github.com/classgraph/classgraph/commit/440849f7523d14fd195debf6e5754f42478f4a33"><code>440849f</code></a> Look up java.lang.System by its fully-qualified name</li> <li><a href="https://github.com/classgraph/classgraph/commit/0820e6ea5e27a9ffa6e6d78d575aa79c4edaba4b"><code>0820e6e</code></a> Update Narcissus to 1.0.12</li> <li><a href="https://github.com/classgraph/classgraph/commit/495a957f14d55b450dc01487e5f876c071656db4"><code>495a957</code></a> Make both reflection drivers agree on static and non-static members</li> <li><a href="https://github.com/classgraph/classgraph/commit/e5b9998101bb592589af2b76a471e3a9972f71f6"><code>e5b9998</code></a> Check for this test's remapped URL rather than assuming it is the only one</li> <li><a href="https://github.com/classgraph/classgraph/commit/00efbbd8e74eb9146fac0b7ee12e7f9c41e25be3"><code>00efbbd</code></a> Accept digits in a URL scheme when ordering the classpath</li> <li><a href="https://github.com/classgraph/classgraph/commit/06c1658644ddc6e6fcf8b71a824795df5dad511e"><code>06c1658</code></a> Correct the pre-commit hook's note on why it formats the whole tree</li> <li><a href="https://github.com/classgraph/classgraph/commit/3fd0dd23c3825654bcea964e763f164c72d41acc"><code>3fd0dd2</code></a> Reformat a staged rename too, not just an added or modified file</li> <li><a href="https://github.com/classgraph/classgraph/commit/23b9b61e5ba0c491ba027a3bd0c0eace3e34c27a"><code>23b9b61</code></a> Fix the pre-commit hook</li> <li><a href="https://github.com/classgraph/classgraph/commit/dfc15e4d548670e57fc6bd17a25f3c5d06aa0518"><code>dfc15e4</code></a> Check the test sources with doclint too, minus the "missing" group</li> <li>Additional commits viewable in <a href="https://github.com/classgraph/classgraph/compare/classgraph-4.8.189...classgraph-4.8.193">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
