Skip to content

support .jar file to be scanned in cli #259

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 1, 2025

Conversation

maxandersen
Copy link
Contributor

as mentioned in #257 it would be nice to be able to scan jars.

this pr enables it so you can do things like:

jar -jar forbiddenapis.jar -d /Users/manderse/.m2/repository/io/quarkus/quarkus-core/3.18.1/quarkus-core-3.18.1.jar --allowmissingclasses --bundledsignatures jdk-system-out

or in more compact form with jbang (if you done jbang app install forbiddenapis.jar

forbiddenapis -d jbang info jar io.quarkus:quarkus-core:3.18.1 --allowmissingclasses --bundledsignatures jdk-system-out

wdyt? I find this superuseful as i can check any maven artifact or even lib on disk without changing their build.

@uschindler
Copy link
Member

uschindler commented Feb 2, 2025

There is no need to extract the JAR to a temporary directory. The Checker API can directly consume the InputStream when you pass them one by one. It must just handle a JAR file like a directory. Of course the classfile pattern needs to be applied, too.

So the JAR file must be serially be passed to:

public void addClassToCheck(final InputStream in, String name) throws IOException {
final ClassReader reader;
try (final InputStream in_ = in) {
reader = AsmUtils.readAndPatchClass(in_);
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException(String.format(Locale.ENGLISH,
"The class file format of '%s' is too recent to be parsed by ASM.", name));
}
final ClassMetadata metadata = new ClassMetadata(reader, false, true);
classesToCheck.put(metadata.getBinaryClassName(), metadata);
}

I can take your PR as a base, but the implementation is not ideal, so I won't merge this as is. To make this work more modifications are needed.

@maxandersen
Copy link
Contributor Author

@uschindler I was wondering what could work but as i couldn't get any of my ides to import all the deps via ivy/build.xml I didn't get that far :)

if you can take it from here and make it work right that would be cool - if not let me know and I'll try do it.

@uschindler
Copy link
Member

No problem, will fix that. I have some ideas. Basically I would use a ZIPInputStream instead, so the ZIP file is read sequentially. I just have to figure out how to apply the glob-based filtering there, I think its somewhere in plexus-utils to apply it to strings.

@dweiss
Copy link
Contributor

dweiss commented Feb 2, 2025

If you stick to NIO then you can use Path as an abstraction for file system files (.class files) and .class files inside ZIP archives (by opening a zip FileSystem [1]).

There is usually some awkwardness in closing zip file systems but they work very well and are robust in my experience. For any downstream code, a Path (and streams) to a file inside a zip archive appears just as a normal filesystem path.

[1] https://docs.oracle.com/en/java/javase/22/docs/api/jdk.zipfs/module-summary.html

@dweiss
Copy link
Contributor

dweiss commented Feb 2, 2025

As for globbing, I've also used glob PathMatcher instances on those zip filesystems and they tend to work quite fine. Again: there are some oddities here and there but they do work, generally.

@uschindler
Copy link
Member

I am working on fixing tis. For the glob pattern matching I use the Plexus SelectorUtils, which are also used by DirectoryScanner, too.

I will also add a patch. I will use your branch and merge the PR later.

@uschindler uschindler force-pushed the scanjar branch 2 times, most recently from c0627bd to 88ac0a2 Compare March 31, 2025 23:42
@uschindler
Copy link
Member

I have now a version that loads the class files directly from the JAR files with the includes/excludes handling from plexus.

@uschindler
Copy link
Member

I will do some further checks and merge this later. With ZIP files you have to be a little bit careful to correctly apply patterns, because the separator (slash or backslash) can be both used. Also you need to possibly normalize the names and remove trailing slashes.

@uschindler
Copy link
Member

I will add a test to the testsuite who parses forbiddenapis own jar with the CLI.

@uschindler uschindler self-assigned this Apr 1, 2025
@uschindler uschindler added this to the 3.9 milestone Apr 1, 2025
@uschindler
Copy link
Member

Testsuite added and issues with pattern matching resolved (original code was using wrong method in SelectorUtils).

@uschindler uschindler merged commit 9520c27 into policeman-tools:main Apr 1, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

3 participants