From 341f35a6f969b1c9bf4d098b9feeacdbfe9d91c7 Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Fri, 28 Feb 2020 22:17:01 +0000 Subject: [PATCH 01/21] 0.5.0: Start dev cycle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 27d75d1..01e19d9 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ subprojects { group = 'org.cadixdev' archivesBaseName = project.name.toLowerCase() - version = '0.4.0' + version = '0.5.0-SNAPSHOT' repositories { mavenCentral() From 9536ffa5a67fd8b50a0fa35d16f9a7624022df01 Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Tue, 11 Aug 2020 20:03:51 +0100 Subject: [PATCH 02/21] Add reader for method signatures --- .../cadixdev/bombe/type/MethodDescriptor.java | 2 +- .../bombe/type/MethodDescriptorReader.java | 2 +- .../bombe/type/signature/MethodSignature.java | 3 +- .../type/signature/MethodSignatureReader.java | 65 +++++++++++++++++++ 4 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 bombe/src/main/java/org/cadixdev/bombe/type/signature/MethodSignatureReader.java diff --git a/bombe/src/main/java/org/cadixdev/bombe/type/MethodDescriptor.java b/bombe/src/main/java/org/cadixdev/bombe/type/MethodDescriptor.java index e094bb0..b84fc51 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/type/MethodDescriptor.java +++ b/bombe/src/main/java/org/cadixdev/bombe/type/MethodDescriptor.java @@ -62,7 +62,7 @@ public final class MethodDescriptor { * @return The descriptor */ public static MethodDescriptor of(final String descriptor) { - return new MethodDescriptorReader(descriptor).read(); + return new MethodDescriptorReader(descriptor).readDescriptor(); } /** diff --git a/bombe/src/main/java/org/cadixdev/bombe/type/MethodDescriptorReader.java b/bombe/src/main/java/org/cadixdev/bombe/type/MethodDescriptorReader.java index 4442559..eb2795e 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/type/MethodDescriptorReader.java +++ b/bombe/src/main/java/org/cadixdev/bombe/type/MethodDescriptorReader.java @@ -54,7 +54,7 @@ public MethodDescriptorReader(final String descriptor) { * @return The type * @throws IllegalStateException If the descriptor is invalid */ - public MethodDescriptor read() { + public MethodDescriptor readDescriptor() { final List params = new ArrayList<>(); if (this.peek() != '(') throw new IllegalStateException("Invalid descriptor provided!"); diff --git a/bombe/src/main/java/org/cadixdev/bombe/type/signature/MethodSignature.java b/bombe/src/main/java/org/cadixdev/bombe/type/signature/MethodSignature.java index 5baaf1f..1f3320a 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/type/signature/MethodSignature.java +++ b/bombe/src/main/java/org/cadixdev/bombe/type/signature/MethodSignature.java @@ -65,8 +65,7 @@ public static MethodSignature of(final String name, final String descriptor) { * @return The new method signature */ public static MethodSignature of(final String nameAndDescriptor) { - int methodIndex = nameAndDescriptor.indexOf('('); - return of(nameAndDescriptor.substring(0, methodIndex), nameAndDescriptor.substring(methodIndex)); + return new MethodSignatureReader(nameAndDescriptor).readSignature(); } /** diff --git a/bombe/src/main/java/org/cadixdev/bombe/type/signature/MethodSignatureReader.java b/bombe/src/main/java/org/cadixdev/bombe/type/signature/MethodSignatureReader.java new file mode 100644 index 0000000..6e3c965 --- /dev/null +++ b/bombe/src/main/java/org/cadixdev/bombe/type/signature/MethodSignatureReader.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018, Jamie Mansfield + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.cadixdev.bombe.type.signature; + +import me.jamiemansfield.string.StringReader; +import org.cadixdev.bombe.type.MethodDescriptorReader; + +/** + * An {@link StringReader} for reading {@link MethodSignature}s + * from their raw {@link String} representation. + * + * @author Jamie Mansfield + * @since 0.5.0 + */ +public class MethodSignatureReader extends MethodDescriptorReader { + + public MethodSignatureReader(final String signature) { + super(signature); + } + + /** + * Reads the next {@link MethodSignature} from source. + * + * @return The type + * @throws IllegalStateException If the signature is invalid + */ + public MethodSignature readSignature() { + final int start = this.index(); + while (this.peek() != '(') { + this.advance(); + } + final String name = this.substring(start, this.index()); + + return new MethodSignature(name, this.readDescriptor()); + } + +} From 212dea47622a410a834814aafee85a4f107f8f74 Mon Sep 17 00:00:00 2001 From: Zach Levis Date: Mon, 7 Sep 2020 20:50:00 -0700 Subject: [PATCH 03/21] Resolve split package between bombe and bombe-jar --- .../bombe/analysis/asm/ClassProviderInheritanceProvider.java | 2 +- .../bombe/{jar => provider}/ClassLoaderClassProvider.java | 2 +- .../org/cadixdev/bombe/{jar => provider}/ClassProvider.java | 2 +- .../cadixdev/bombe/{jar => provider}/JarFileClassProvider.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename bombe/src/main/java/org/cadixdev/bombe/{jar => provider}/ClassLoaderClassProvider.java (98%) rename bombe/src/main/java/org/cadixdev/bombe/{jar => provider}/ClassProvider.java (98%) rename bombe/src/main/java/org/cadixdev/bombe/{jar => provider}/JarFileClassProvider.java (98%) diff --git a/bombe/src/main/java/org/cadixdev/bombe/analysis/asm/ClassProviderInheritanceProvider.java b/bombe/src/main/java/org/cadixdev/bombe/analysis/asm/ClassProviderInheritanceProvider.java index b178a31..da70c5b 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/analysis/asm/ClassProviderInheritanceProvider.java +++ b/bombe/src/main/java/org/cadixdev/bombe/analysis/asm/ClassProviderInheritanceProvider.java @@ -31,7 +31,7 @@ package org.cadixdev.bombe.analysis.asm; import org.cadixdev.bombe.analysis.InheritanceProvider; -import org.cadixdev.bombe.jar.ClassProvider; +import org.cadixdev.bombe.provider.ClassProvider; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Opcodes; diff --git a/bombe/src/main/java/org/cadixdev/bombe/jar/ClassLoaderClassProvider.java b/bombe/src/main/java/org/cadixdev/bombe/provider/ClassLoaderClassProvider.java similarity index 98% rename from bombe/src/main/java/org/cadixdev/bombe/jar/ClassLoaderClassProvider.java rename to bombe/src/main/java/org/cadixdev/bombe/provider/ClassLoaderClassProvider.java index 9cb645c..99ef6c7 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/jar/ClassLoaderClassProvider.java +++ b/bombe/src/main/java/org/cadixdev/bombe/provider/ClassLoaderClassProvider.java @@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.cadixdev.bombe.jar; +package org.cadixdev.bombe.provider; import org.cadixdev.bombe.util.ByteStreams; diff --git a/bombe/src/main/java/org/cadixdev/bombe/jar/ClassProvider.java b/bombe/src/main/java/org/cadixdev/bombe/provider/ClassProvider.java similarity index 98% rename from bombe/src/main/java/org/cadixdev/bombe/jar/ClassProvider.java rename to bombe/src/main/java/org/cadixdev/bombe/provider/ClassProvider.java index 011c060..a0a5e41 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/jar/ClassProvider.java +++ b/bombe/src/main/java/org/cadixdev/bombe/provider/ClassProvider.java @@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.cadixdev.bombe.jar; +package org.cadixdev.bombe.provider; import org.objectweb.asm.ClassReader; import org.objectweb.asm.tree.ClassNode; diff --git a/bombe/src/main/java/org/cadixdev/bombe/jar/JarFileClassProvider.java b/bombe/src/main/java/org/cadixdev/bombe/provider/JarFileClassProvider.java similarity index 98% rename from bombe/src/main/java/org/cadixdev/bombe/jar/JarFileClassProvider.java rename to bombe/src/main/java/org/cadixdev/bombe/provider/JarFileClassProvider.java index c898326..d771332 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/jar/JarFileClassProvider.java +++ b/bombe/src/main/java/org/cadixdev/bombe/provider/JarFileClassProvider.java @@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.cadixdev.bombe.jar; +package org.cadixdev.bombe.provider; import org.cadixdev.bombe.util.ByteStreams; From 9b773ce3f6c3e8cee574ed95a86b068e763426d1 Mon Sep 17 00:00:00 2001 From: Zach Levis Date: Mon, 7 Sep 2020 21:11:46 -0700 Subject: [PATCH 04/21] Add Automatic-Module-Name --- bombe-jar/build.gradle | 8 +++++++- bombe/build.gradle | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/bombe-jar/build.gradle b/bombe-jar/build.gradle index 3dd1e0b..aca9bf7 100644 --- a/bombe-jar/build.gradle +++ b/bombe-jar/build.gradle @@ -2,4 +2,10 @@ dependencies { compile project(':bombe') compileOnly "org.ow2.asm:asm-commons:$asmVersion" testCompile "org.ow2.asm:asm-commons:$asmVersion" -} \ No newline at end of file +} + +jar { + manifest.attributes( + 'Automatic-Module-Name': "${project.group}.bombe.jar" + ) +} diff --git a/bombe/build.gradle b/bombe/build.gradle index e195ca9..9e031e9 100644 --- a/bombe/build.gradle +++ b/bombe/build.gradle @@ -3,3 +3,10 @@ dependencies { compileOnly "org.ow2.asm:asm-commons:$asmVersion" testCompile "org.ow2.asm:asm-commons:$asmVersion" } + +jar { + manifest.attributes( + 'Automatic-Module-Name': "${project.group}.bombe" + ) +} + From daadc460866c70ac8a6b4c8a3d0b8e9a72badd7c Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Sat, 2 Jan 2021 22:27:49 +0000 Subject: [PATCH 05/21] Pull CompositeClassProvider from Atlas --- .../provider/CompositeClassProvider.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 bombe/src/main/java/org/cadixdev/bombe/provider/CompositeClassProvider.java diff --git a/bombe/src/main/java/org/cadixdev/bombe/provider/CompositeClassProvider.java b/bombe/src/main/java/org/cadixdev/bombe/provider/CompositeClassProvider.java new file mode 100644 index 0000000..20f0738 --- /dev/null +++ b/bombe/src/main/java/org/cadixdev/bombe/provider/CompositeClassProvider.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018, Jamie Mansfield + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.cadixdev.bombe.provider; + +import java.util.List; + +/** + * A {@link ClassProvider class provider} backed by many other class providers. + * + * @author Jamie Mansfield + * @since 0.5.0 + */ +public class CompositeClassProvider implements ClassProvider { + + private final List providers; + + public CompositeClassProvider(final List providers) { + this.providers = providers; + } + + @Override + public byte[] get(final String klass) { + for (final ClassProvider provider : this.providers) { + final byte[] raw = provider.get(klass); + if (raw != null) return raw; + } + return null; + } + +} From 7384cc2949bcc495534a3f18fbb24a355f9e4594 Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Sat, 2 Jan 2021 22:33:45 +0000 Subject: [PATCH 06/21] Replace Guava i/o copy with our own Thanks to @DemonWav for this implementation :) --- .../org/cadixdev/bombe/util/ByteStreams.java | 67 ++++++------------- 1 file changed, 21 insertions(+), 46 deletions(-) diff --git a/bombe/src/main/java/org/cadixdev/bombe/util/ByteStreams.java b/bombe/src/main/java/org/cadixdev/bombe/util/ByteStreams.java index e262b14..1f8decc 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/util/ByteStreams.java +++ b/bombe/src/main/java/org/cadixdev/bombe/util/ByteStreams.java @@ -37,62 +37,37 @@ /** * Utility for working with byte streams. * - * @author Guava Authors + * @author Kyle Wood * @since 0.3.0 */ public final class ByteStreams { - // ------------------------------------------------ - // The following code is taken from Guava (d0d5bd7) - // - // The code remains mostly untouched, only style-differences are present. - // ------------------------------------------------ - // Copyright (C) 2007 The Guava Authors - // - // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - // in compliance with the License. You may obtain a copy of the License at - // - // http://www.apache.org/licenses/LICENSE-2.0 - // - // Unless required by applicable law or agreed to in writing, software distributed under the License - // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - // or implied. See the License for the specific language governing permissions and limitations under - // the License. - // ------------------------------------------------ - - private static final int BUFFER_SIZE = 8192; - - /** Creates a new byte array for buffering reads or writes. */ - private static byte[] createBuffer() { - return new byte[BUFFER_SIZE]; - } - /** - * Copies all bytes from the input stream to the output stream. Does not close or flush either - * stream. + * Copy all of the data from the {@code from} input to the {@code to} output. * - * @param from the input stream to read from - * @param to the output stream to write to - * @return the number of bytes copied - * @throws IOException if an I/O error occurs + * @param from The input to copy from. + * @param to The output to copy to. + * @param buffer The byte array to use as the copy buffer. + * @throws IOException If an IO error occurs. */ - public static long copy(final InputStream from, final OutputStream to) throws IOException { - final byte[] buf = createBuffer(); - long total = 0; - while (true) { - final int r = from.read(buf); - if (r == -1) { - break; - } - to.write(buf, 0, r); - total += r; + public static void copy(final InputStream from, final OutputStream to, final byte[] buffer) throws IOException { + int read; + while ((read = from.read(buffer)) != -1) { + to.write(buffer, 0, read); } - return total; } - // ------------------------------------------------ - // End of Apache-licensed Guava code. - // ------------------------------------------------ + /** + * Copy all of the data from the {@code from} input to the {@code to} output, + * using a default buffer. + * + * @param from The input to copy from. + * @param to The output to copy to. + * @throws IOException If an IO error occurs. + */ + public static void copy(final InputStream from, final OutputStream to) throws IOException { + copy(from, to, new byte[8192]); + } private ByteStreams() { } From addddbb88fddcc2b756c555cf097afa97e80ccc4 Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Mon, 1 Feb 2021 14:20:34 +0000 Subject: [PATCH 07/21] Use Attributes.Name.MAIN_CLASS --- .../bombe/jar/asm/JarEntryRemappingTransformer.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/bombe-jar/src/main/java/org/cadixdev/bombe/jar/asm/JarEntryRemappingTransformer.java b/bombe-jar/src/main/java/org/cadixdev/bombe/jar/asm/JarEntryRemappingTransformer.java index 9252265..87cfac7 100644 --- a/bombe-jar/src/main/java/org/cadixdev/bombe/jar/asm/JarEntryRemappingTransformer.java +++ b/bombe-jar/src/main/java/org/cadixdev/bombe/jar/asm/JarEntryRemappingTransformer.java @@ -30,6 +30,8 @@ package org.cadixdev.bombe.jar.asm; +import static java.util.jar.Attributes.Name.MAIN_CLASS; + import org.cadixdev.bombe.jar.JarClassEntry; import org.cadixdev.bombe.jar.JarEntryTransformer; import org.cadixdev.bombe.jar.JarManifestEntry; @@ -43,7 +45,6 @@ import java.util.List; import java.util.function.BiFunction; -import java.util.jar.Attributes; import java.util.stream.Collectors; /** @@ -86,14 +87,14 @@ public JarClassEntry transform(final JarClassEntry entry) { @Override public JarManifestEntry transform(final JarManifestEntry entry) { // Remap the Main-Class attribute, if present - if (entry.getManifest().getMainAttributes().containsKey(new Attributes.Name("Main-Class"))) { - final String mainClassObf = entry.getManifest().getMainAttributes().getValue("Main-Class") + if (entry.getManifest().getMainAttributes().containsKey(MAIN_CLASS)) { + final String mainClassObf = entry.getManifest().getMainAttributes().getValue(MAIN_CLASS) .replace('.', '/'); final String mainClassDeobf = this.remapper.map(mainClassObf) .replace('/', '.'); - // Since Manifest is mutable, we need'nt create a new entry \o/ - entry.getManifest().getMainAttributes().putValue("Main-Class", mainClassDeobf); + // Since Manifest is mutable, we needn't create a new entry \o/ + entry.getManifest().getMainAttributes().put(MAIN_CLASS, mainClassDeobf); } return entry; From 9fbe60e40f0609f73f6c04465ca4b00724e803ea Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Mon, 1 Feb 2021 14:39:31 +0000 Subject: [PATCH 08/21] Update Gradle wrapper, Groovy, and Spock Also remove the 'vintage' junit runner, and fix compile issues on compilers newer than Java 8. --- .travis.yml | 2 +- bombe-jar/build.gradle | 6 +- bombe/build.gradle | 6 +- .../bombe/analysis/InheritanceProvider.java | 2 +- build.gradle | 159 ++++++++---------- gradle/wrapper/gradle-wrapper.jar | Bin 54329 -> 54413 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- 7 files changed, 83 insertions(+), 94 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1bcb5bb..c0bd58d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ script: - ./gradlew build - ./gradlew codeCoverageReport after_success: - - '[[ "$TRAVIS_PULL_REQUEST" = "false" && "$TRAVIS_BRANCH" = "develop" ]] && ./gradlew uploadArchives' + - '[[ "$TRAVIS_PULL_REQUEST" = "false" && "$TRAVIS_BRANCH" = "develop" ]] && ./gradlew publish' - bash <(curl -s https://codecov.io/bash) # Ugh. diff --git a/bombe-jar/build.gradle b/bombe-jar/build.gradle index aca9bf7..8a6e7f3 100644 --- a/bombe-jar/build.gradle +++ b/bombe-jar/build.gradle @@ -1,7 +1,7 @@ dependencies { - compile project(':bombe') - compileOnly "org.ow2.asm:asm-commons:$asmVersion" - testCompile "org.ow2.asm:asm-commons:$asmVersion" + api project(':bombe') + implementation "org.ow2.asm:asm-commons:$asmVersion" + testImplementation "org.ow2.asm:asm-commons:$asmVersion" } jar { diff --git a/bombe/build.gradle b/bombe/build.gradle index 9e031e9..10b7abb 100644 --- a/bombe/build.gradle +++ b/bombe/build.gradle @@ -1,7 +1,7 @@ dependencies { - compile "me.jamiemansfield:string:$stringVersion" - compileOnly "org.ow2.asm:asm-commons:$asmVersion" - testCompile "org.ow2.asm:asm-commons:$asmVersion" + api "me.jamiemansfield:string:$stringVersion" + implementation "org.ow2.asm:asm-commons:$asmVersion" + testImplementation "org.ow2.asm:asm-commons:$asmVersion" } jar { diff --git a/bombe/src/main/java/org/cadixdev/bombe/analysis/InheritanceProvider.java b/bombe/src/main/java/org/cadixdev/bombe/analysis/InheritanceProvider.java index 03bf094..7d85bb4 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/analysis/InheritanceProvider.java +++ b/bombe/src/main/java/org/cadixdev/bombe/analysis/InheritanceProvider.java @@ -432,7 +432,7 @@ public Map getMethods() { @Override public Set provideParents(final InheritanceProvider provider) { if (this.parents == null) { - ClassInfo.super.provideParents(provider, this.parents = new HashSet<>()); + super.provideParents(provider, this.parents = new HashSet<>()); } return this.parents; } diff --git a/build.gradle b/build.gradle index 01e19d9..f11cf63 100644 --- a/build.gradle +++ b/build.gradle @@ -7,12 +7,17 @@ allprojects { } subprojects { - apply plugin: 'java' + apply plugin: 'java-library' apply plugin: 'groovy' - apply plugin: 'maven' + apply plugin: 'maven-publish' - sourceCompatibility = '1.8' - targetCompatibility = '1.8' + java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + + withJavadocJar() + withSourcesJar() + } group = 'org.cadixdev' archivesBaseName = project.name.toLowerCase() @@ -23,11 +28,10 @@ subprojects { } dependencies { - testCompile 'org.codehaus.groovy:groovy-all:2.5.8' - testCompile 'org.spockframework:spock-core:1.3-groovy-2.5' - testCompile 'org.junit.jupiter:junit-jupiter-api:5.5.1' - testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.5.1' - testRuntime 'org.junit.vintage:junit-vintage-engine:5.5.1' + testImplementation 'org.codehaus.groovy:groovy-all:3.0.7' + testImplementation 'org.spockframework:spock-core:2.0-M4-groovy-3.0' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.1' + testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.5.1' } test { @@ -46,96 +50,81 @@ subprojects { ) } - task javadocJar(type: Jar, dependsOn: 'javadoc') { - from javadoc.destinationDir - classifier = 'javadoc' - } + publishing { + publications { + mavenJava(MavenPublication) { + artifactId = project.archivesBaseName + from components.java - task sourcesJar(type: Jar, dependsOn: 'classes') { - from sourceSets.main.allSource - classifier = 'sources' - } + pom { + name = project.name + description = project.description + packaging = 'jar' + url = project.url + inceptionYear = project.inceptionYear + + scm { + url = 'https://github.com/CadixDev/Bombe' + connection = 'scm:git:https://github.com/CadixDev/Bombe.git' + developerConnection = 'scm:git:git@github.com:CadixDev/Bombe.git' + } - artifacts { - archives javadocJar - archives sourcesJar - } + issueManagement { + system = 'GitHub' + url = 'https://github.com/CadixDev/Bombe/issues' + } - jacocoTestReport { - reports { - xml.enabled = true - html.enabled = true + licenses { + license { + name = 'BSD 3-Clause' + url = 'https://opensource.org/licenses/BSD-3-Clause' + distribution = 'repo' + } + } + + developers { + developer { + id = 'jamierocks' + name = 'Jamie Mansfield' + email = 'jmansfield@cadixdev.org' + url = 'https://www.jamiemansfield.me/' + timezone = 'Europe/London' + } + } + } + } + } + repositories { + if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')) { + maven { + url = !version.endsWith('-SNAPSHOT') ? + 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' : + 'https://oss.sonatype.org/content/repositories/snapshots/' + + credentials { + username = ossrhUsername + password = ossrhPassword + } + } + } } } - check.dependsOn jacocoTestReport if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')) { apply plugin: 'signing' signing { - required { !version.endsWith('-SNAPSHOT') && gradle.taskGraph.hasTask(tasks.uploadArchives) } - sign configurations.archives + required { !version.endsWith('-SNAPSHOT') && gradle.taskGraph.hasTask(tasks.publish) } + sign publishing.publications.mavenJava } } - uploadArchives { - repositories { - mavenDeployer { - // Maven Central - if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')) { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - - repository(url: 'https://oss.sonatype.org/service/local/staging/deploy/maven2/') { - authentication(userName: ossrhUsername, password: ossrhPassword) - } - - snapshotRepository(url: 'https://oss.sonatype.org/content/repositories/snapshots/') { - authentication(userName: ossrhUsername, password: ossrhPassword) - } - } - - pom { - artifactId = project.archivesBaseName - - project { - name = project.name - description = project.description - packaging = 'jar' - url = project.url - inceptionYear = project.inceptionYear - - scm { - url = 'https://github.com/CadixDev/Bombe' - connection = 'scm:git:https://github.com/CadixDev/Bombe.git' - developerConnection = 'scm:git:git@github.com:CadixDev/Bombe.git' - } - - issueManagement { - system = 'GitHub' - url = 'https://github.com/CadixDev/Bombe/issues' - } - - licenses { - license { - name = 'BSD 3-Clause' - url = 'https://opensource.org/licenses/BSD-3-Clause' - distribution = 'repo' - } - } - - developers { - developer { - id = 'jamierocks' - name = 'Jamie Mansfield' - email = 'dev@jamierocks.uk' - url = 'https://www.jamiemansfield.me/' - timezone = 'Europe/London' - } - } - } - } - } + jacocoTestReport { + reports { + xml.enabled = true + html.enabled = true } } + check.dependsOn jacocoTestReport } task codeCoverageReport(type: JacocoReport) { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a5fe1cb94b9ee5ce57e6113458225bcba12d83e3..0d4a9516871afd710a9d84d89e31ba77745607bd 100644 GIT binary patch delta 7399 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 Kp$_){$NV2Uh7M%_ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 949819d..28ff446 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip From 9dde46834ca913a14e6b9d2e2e6e6c6146b86399 Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Fri, 5 Feb 2021 21:46:33 +0000 Subject: [PATCH 09/21] 0.3.5: Begin dev cycle --- build.gradle | 2 +- changelogs/0.3.5.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changelogs/0.3.5.md diff --git a/build.gradle b/build.gradle index 1ff6f10..91fe2f6 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ subprojects { group = 'org.cadixdev' archivesBaseName = project.name.toLowerCase() - version = '0.3.4' + version = '0.3.5-SNAPSHOT' repositories { mavenCentral() diff --git a/changelogs/0.3.5.md b/changelogs/0.3.5.md new file mode 100644 index 0000000..611152e --- /dev/null +++ b/changelogs/0.3.5.md @@ -0,0 +1,4 @@ +Bombe 0.3.5 +=== + +TODO From cc2c082082d54ea96cdd518b97cae65e3c1f4af4 Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Fri, 5 Feb 2021 21:48:30 +0000 Subject: [PATCH 10/21] Deprecate legacy Jars utility Atlas has been the replacement for a while, everyone should migrate to it. This is mostly a formality that was missed. --- bombe/src/main/java/org/cadixdev/bombe/jar/Jars.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bombe/src/main/java/org/cadixdev/bombe/jar/Jars.java b/bombe/src/main/java/org/cadixdev/bombe/jar/Jars.java index 336dabf..2d4fa24 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/jar/Jars.java +++ b/bombe/src/main/java/org/cadixdev/bombe/jar/Jars.java @@ -51,7 +51,9 @@ * * @author Jamie Mansfield * @since 0.3.0 + * @deprecated 0.3.5 - Migrate to Atlas */ +@Deprecated public final class Jars { /** From bcd1576ce8aecb1f286ab1eab252e77d85fc0141 Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Fri, 5 Feb 2021 21:54:10 +0000 Subject: [PATCH 11/21] Allow transformers to mark entries for removal This change documents a feature previously added to Atlas [1], and introduces support (since the API is still available) to the legacy Jars utility. [1] https://github.com/CadixDev/Atlas/commit/bb22f810d0db318f6ac9843529b3a198c47efacf --- .../bombe/jar/JarEntryTransformer.java | 20 +++++++++++++++---- .../java/org/cadixdev/bombe/jar/Jars.java | 3 +++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/bombe/src/main/java/org/cadixdev/bombe/jar/JarEntryTransformer.java b/bombe/src/main/java/org/cadixdev/bombe/jar/JarEntryTransformer.java index 95f0865..8fea0f3 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/jar/JarEntryTransformer.java +++ b/bombe/src/main/java/org/cadixdev/bombe/jar/JarEntryTransformer.java @@ -41,9 +41,12 @@ public interface JarEntryTransformer { /** * Transforms the given class entry. + *

+ * It is possible to remove entries by returning {@code null}, when this + * occurs no further transformers will process the entry. * * @param entry The class entry - * @return The transformed entry + * @return The transformed entry, or {@code null} if the entry should be removed */ default JarClassEntry transform(final JarClassEntry entry) { return entry; @@ -51,9 +54,12 @@ default JarClassEntry transform(final JarClassEntry entry) { /** * Transforms the given resource entry. + *

+ * It is possible to remove entries by returning {@code null}, when this + * occurs no further transformers will process the entry. * * @param entry The resource entry - * @return The transformed entry + * @return The transformed entry, or {@code null} if the entry should be removed */ default JarResourceEntry transform(final JarResourceEntry entry) { return entry; @@ -61,9 +67,12 @@ default JarResourceEntry transform(final JarResourceEntry entry) { /** * Transforms the given manifest entry. + *

+ * It is possible to remove entries by returning {@code null}, when this + * occurs no further transformers will process the entry. * * @param entry The manifest entry - * @return The transformed entry + * @return The transformed entry, or {@code null} if the entry should be removed */ default JarManifestEntry transform(final JarManifestEntry entry) { return entry; @@ -71,9 +80,12 @@ default JarManifestEntry transform(final JarManifestEntry entry) { /** * Transforms the given service provider configuration entry. + *

+ * It is possible to remove entries by returning {@code null}, when this + * occurs no further transformers will process the entry. * * @param entry The service provider configuration entry - * @return The transformed entry + * @return The transformed entry, or {@code null} if the entry should be removed */ default JarServiceProviderConfigurationEntry transform(final JarServiceProviderConfigurationEntry entry) { return entry; diff --git a/bombe/src/main/java/org/cadixdev/bombe/jar/Jars.java b/bombe/src/main/java/org/cadixdev/bombe/jar/Jars.java index 2d4fa24..bb81481 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/jar/Jars.java +++ b/bombe/src/main/java/org/cadixdev/bombe/jar/Jars.java @@ -127,9 +127,12 @@ public static JarOutputStream transform(final JarFile jarFile, final JarOutputSt .map(entry -> { for (final JarEntryTransformer transformer : transformers) { entry = entry.accept(transformer); + + if (entry == null) return null; } return entry; }) + .filter(Objects::nonNull) .forEach(entry -> { try { if (!packages.contains(entry.getPackage())) { From d542c2085a0c5bfc3452f8cc7c0536e43d6e0ba4 Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Fri, 5 Feb 2021 22:01:57 +0000 Subject: [PATCH 12/21] Allow transformers to introduce entries --- .../org/cadixdev/bombe/jar/JarEntryTransformer.java | 13 +++++++++++++ .../src/main/java/org/cadixdev/bombe/jar/Jars.java | 13 ++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/bombe/src/main/java/org/cadixdev/bombe/jar/JarEntryTransformer.java b/bombe/src/main/java/org/cadixdev/bombe/jar/JarEntryTransformer.java index 8fea0f3..a16bfac 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/jar/JarEntryTransformer.java +++ b/bombe/src/main/java/org/cadixdev/bombe/jar/JarEntryTransformer.java @@ -30,6 +30,9 @@ package org.cadixdev.bombe.jar; +import java.util.Collections; +import java.util.List; + /** * A visitor for {@link AbstractJarEntry}, allowing them be be * transformed. @@ -91,4 +94,14 @@ default JarServiceProviderConfigurationEntry transform(final JarServiceProviderC return entry; } + /** + * Provides a list of {@link AbstractJarEntry jar entries} to add into the + * processed jar file. + * + * @return Entries to add into the final jar + */ + default List additions() { + return Collections.emptyList(); + } + } diff --git a/bombe/src/main/java/org/cadixdev/bombe/jar/Jars.java b/bombe/src/main/java/org/cadixdev/bombe/jar/Jars.java index bb81481..67ebb87 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/jar/Jars.java +++ b/bombe/src/main/java/org/cadixdev/bombe/jar/Jars.java @@ -37,6 +37,8 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; +import java.util.Collection; import java.util.HashSet; import java.util.Objects; import java.util.Set; @@ -122,8 +124,7 @@ public static void transform(final Path input, final Path output, final JarEntry * @return The jar output stream */ public static JarOutputStream transform(final JarFile jarFile, final JarOutputStream jos, final JarEntryTransformer... transformers) { - final Set packages = new HashSet<>(); - walk(jarFile) + final Stream transformations = walk(jarFile) .map(entry -> { for (final JarEntryTransformer transformer : transformers) { entry = entry.accept(transformer); @@ -132,7 +133,13 @@ public static JarOutputStream transform(final JarFile jarFile, final JarOutputSt } return entry; }) - .filter(Objects::nonNull) + .filter(Objects::nonNull); + final Stream additions = Arrays.stream(transformers) + .map(JarEntryTransformer::additions) + .flatMap(Collection::stream); + + final Set packages = new HashSet<>(); + Stream.concat(transformations, additions) .forEach(entry -> { try { if (!packages.contains(entry.getPackage())) { From 44f1cedc3e861ecd684390cb196d8bc6ae1cf1bd Mon Sep 17 00:00:00 2001 From: Zach Levis Date: Fri, 5 Feb 2021 14:24:00 -0800 Subject: [PATCH 13/21] asm: Strip jar file signatures in the remapping transformer --- .../asm/jar/JarEntryRemappingTransformer.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/bombe-asm/src/main/java/org/cadixdev/bombe/asm/jar/JarEntryRemappingTransformer.java b/bombe-asm/src/main/java/org/cadixdev/bombe/asm/jar/JarEntryRemappingTransformer.java index 2cbd9bc..d70380f 100644 --- a/bombe-asm/src/main/java/org/cadixdev/bombe/asm/jar/JarEntryRemappingTransformer.java +++ b/bombe-asm/src/main/java/org/cadixdev/bombe/asm/jar/JarEntryRemappingTransformer.java @@ -33,6 +33,7 @@ import org.cadixdev.bombe.jar.JarClassEntry; import org.cadixdev.bombe.jar.JarEntryTransformer; import org.cadixdev.bombe.jar.JarManifestEntry; +import org.cadixdev.bombe.jar.JarResourceEntry; import org.cadixdev.bombe.jar.JarServiceProviderConfigurationEntry; import org.cadixdev.bombe.jar.ServiceProviderConfiguration; import org.objectweb.asm.ClassReader; @@ -41,7 +42,9 @@ import org.objectweb.asm.commons.ClassRemapper; import org.objectweb.asm.commons.Remapper; +import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.function.BiFunction; import java.util.jar.Attributes; import java.util.stream.Collectors; @@ -55,6 +58,8 @@ */ public class JarEntryRemappingTransformer implements JarEntryTransformer { + private static final Attributes.Name SHA_256_DIGEST = new Attributes.Name("SHA-256-Digest"); + private final Remapper remapper; private final BiFunction clsRemapper; @@ -96,6 +101,16 @@ public JarManifestEntry transform(final JarManifestEntry entry) { entry.getManifest().getMainAttributes().putValue("Main-Class", mainClassDeobf); } + // Remove all signature entries + for (final Iterator> it = entry.getManifest().getEntries().entrySet().iterator(); it.hasNext();) { + final Map.Entry section = it.next(); + if (section.getValue().remove(SHA_256_DIGEST) != null) { + if (section.getValue().isEmpty()) { + it.remove(); + } + } + } + return entry; } @@ -119,4 +134,15 @@ public JarServiceProviderConfigurationEntry transform(final JarServiceProviderCo return new JarServiceProviderConfigurationEntry(entry.getTime(), config); } + @Override + public JarResourceEntry transform(final JarResourceEntry entry) { + // Strip signature files from metadata + if (entry.getName().startsWith("META-INF")) { + if (entry.getExtension().equals("RSA") + || entry.getExtension().equals("SF")) { + return null; + } + } + return entry; + } } From fec8cd268e735d2b843d8409cc7c47cb8208924c Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Mon, 1 Feb 2021 14:20:34 +0000 Subject: [PATCH 14/21] Use Attributes.Name.MAIN_CLASS --- .../bombe/asm/jar/JarEntryRemappingTransformer.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bombe-asm/src/main/java/org/cadixdev/bombe/asm/jar/JarEntryRemappingTransformer.java b/bombe-asm/src/main/java/org/cadixdev/bombe/asm/jar/JarEntryRemappingTransformer.java index d70380f..e9397e9 100644 --- a/bombe-asm/src/main/java/org/cadixdev/bombe/asm/jar/JarEntryRemappingTransformer.java +++ b/bombe-asm/src/main/java/org/cadixdev/bombe/asm/jar/JarEntryRemappingTransformer.java @@ -30,6 +30,8 @@ package org.cadixdev.bombe.asm.jar; +import static java.util.jar.Attributes.Name.MAIN_CLASS; + import org.cadixdev.bombe.jar.JarClassEntry; import org.cadixdev.bombe.jar.JarEntryTransformer; import org.cadixdev.bombe.jar.JarManifestEntry; @@ -91,14 +93,14 @@ public JarClassEntry transform(final JarClassEntry entry) { @Override public JarManifestEntry transform(final JarManifestEntry entry) { // Remap the Main-Class attribute, if present - if (entry.getManifest().getMainAttributes().containsKey(new Attributes.Name("Main-Class"))) { - final String mainClassObf = entry.getManifest().getMainAttributes().getValue("Main-Class") + if (entry.getManifest().getMainAttributes().containsKey(MAIN_CLASS)) { + final String mainClassObf = entry.getManifest().getMainAttributes().getValue(MAIN_CLASS) .replace('.', '/'); final String mainClassDeobf = this.remapper.map(mainClassObf) .replace('/', '.'); - // Since Manifest is mutable, we need'nt create a new entry \o/ - entry.getManifest().getMainAttributes().putValue("Main-Class", mainClassDeobf); + // Since Manifest is mutable, we needn't create a new entry \o/ + entry.getManifest().getMainAttributes().put(MAIN_CLASS, mainClassDeobf); } // Remove all signature entries From ae08b10d2dedf499d4fde918bb2a7976a1add5d1 Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Tue, 9 Feb 2021 17:46:13 +0000 Subject: [PATCH 15/21] 0.3.5: Release Time --- .../bombe/analysis/InheritanceProvider.java | 2 +- build.gradle | 4 ++-- changelogs/0.3.5.md | 13 ++++++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/bombe/src/main/java/org/cadixdev/bombe/analysis/InheritanceProvider.java b/bombe/src/main/java/org/cadixdev/bombe/analysis/InheritanceProvider.java index 03bf094..7d85bb4 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/analysis/InheritanceProvider.java +++ b/bombe/src/main/java/org/cadixdev/bombe/analysis/InheritanceProvider.java @@ -432,7 +432,7 @@ public Map getMethods() { @Override public Set provideParents(final InheritanceProvider provider) { if (this.parents == null) { - ClassInfo.super.provideParents(provider, this.parents = new HashSet<>()); + super.provideParents(provider, this.parents = new HashSet<>()); } return this.parents; } diff --git a/build.gradle b/build.gradle index 91fe2f6..9269e69 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ subprojects { group = 'org.cadixdev' archivesBaseName = project.name.toLowerCase() - version = '0.3.5-SNAPSHOT' + version = '0.3.5' repositories { mavenCentral() @@ -106,7 +106,7 @@ subprojects { developer { id = 'jamierocks' name = 'Jamie Mansfield' - email = 'dev@jamierocks.uk' + email = 'jmansfield@cadixdev.org' url = 'https://www.jamiemansfield.me/' timezone = 'Europe/London' } diff --git a/changelogs/0.3.5.md b/changelogs/0.3.5.md index 611152e..5f44066 100644 --- a/changelogs/0.3.5.md +++ b/changelogs/0.3.5.md @@ -1,4 +1,15 @@ Bombe 0.3.5 === -TODO +Bombe 0.3.5 is a small release introducing some new APIs to bolster the +capabilities of the jar transformation framework, namely allowing entries to be +introduced. To accomplish this, a `JarEntryTransformer#additions()` method has +been introduced. The `Jars` utility has been updated to support this, and a +release of Atlas will be made shortly to implement this feature. + +The `Jars` utility has been deprecated in this version, advising consumers to +switch to Atlas. Jars was removed in 0.4.0, so this just serves as a final +notice to any lingering applications using the utility. + +The remapping transformer will additionally strip signature files and entries +in the manifest. This transformer may in future be available standalone. From 2137e8e0571198df024ecc5f1dd92ea0e008221e Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Tue, 9 Feb 2021 17:56:33 +0000 Subject: [PATCH 16/21] 0.4.4: Start dev cycle --- build.gradle | 2 +- changelogs/0.4.4.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changelogs/0.4.4.md diff --git a/build.gradle b/build.gradle index ffa8610..06e565f 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ subprojects { group = 'org.cadixdev' archivesBaseName = project.name.toLowerCase() - version = '0.4.3' + version = '0.4.4-SNAPSHOT' repositories { mavenCentral() diff --git a/changelogs/0.4.4.md b/changelogs/0.4.4.md new file mode 100644 index 0000000..1f8ef90 --- /dev/null +++ b/changelogs/0.4.4.md @@ -0,0 +1,4 @@ +Bombe 0.4.4 +=== + +TODO From 66d436c79a738bbc8c6c43338312a9ff7aee61c5 Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Tue, 9 Feb 2021 18:03:29 +0000 Subject: [PATCH 17/21] 0.4.4: Release Time --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 80d025d..952b7f6 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ subprojects { group = 'org.cadixdev' archivesBaseName = project.name.toLowerCase() - version = '0.4.4-SNAPSHOT' + version = '0.4.4' repositories { mavenCentral() From c822ed1baa6b0d03fba664b0f8b0a0d115be790c Mon Sep 17 00:00:00 2001 From: zml Date: Sun, 4 Apr 2021 22:16:14 -0700 Subject: [PATCH 18/21] Basic multi-release jar handling This adds multi-release jar handling to the model and updates the remapping transformer to be aware of that information. --- .../cadixdev/bombe/jar/AbstractJarEntry.java | 107 +++++++++++++++++- .../org/cadixdev/bombe/jar/JarClassEntry.java | 9 +- .../cadixdev/bombe/jar/JarManifestEntry.java | 4 +- .../cadixdev/bombe/jar/JarResourceEntry.java | 9 +- .../JarServiceProviderConfigurationEntry.java | 4 +- .../jar/asm/JarEntryRemappingTransformer.java | 4 +- .../bombe/jar/test/JarEntrySpec.groovy | 23 ++++ .../JarEntryRemappingTransformerSpec.groovy | 22 ++++ 8 files changed, 166 insertions(+), 16 deletions(-) diff --git a/bombe-jar/src/main/java/org/cadixdev/bombe/jar/AbstractJarEntry.java b/bombe-jar/src/main/java/org/cadixdev/bombe/jar/AbstractJarEntry.java index 2dd771f..8b6a285 100644 --- a/bombe-jar/src/main/java/org/cadixdev/bombe/jar/AbstractJarEntry.java +++ b/bombe-jar/src/main/java/org/cadixdev/bombe/jar/AbstractJarEntry.java @@ -32,6 +32,7 @@ import java.io.IOException; import java.util.jar.JarEntry; +import java.util.jar.JarFile; import java.util.jar.JarOutputStream; /** @@ -42,11 +43,44 @@ */ public abstract class AbstractJarEntry { + /** + * A {@link #getVersion()} value for jar entries that are at the base + * version in the jar. + */ + public static final int UNVERSIONED = -1; + + private static final String META_INF = "META-INF/"; + private static final String VERSIONS_PREFIX = META_INF + "versions/"; + protected final String name; protected final long time; + private String unversionedName; + private int version = UNVERSIONED; private String packageName; private String simpleName; + /** + * Create a new jar entry for a specific multi-release variant. + * + *

If {@code unversionedName} starts with {@code META-INF}, it will be + * treated as being in the base version no matter what value is provided for + * {@code version}, to match the behavior of the JDK's {@link JarFile}.

+ * + * @param version the Java version number to associate this entry with + * @param unversionedName the name without any versioned prefix + * @param time the time the entry was created at + */ + protected AbstractJarEntry(final int version, final String unversionedName, final long time) { + if (version == UNVERSIONED || unversionedName.startsWith(META_INF)) { + this.name = unversionedName; + } else { + this.version = version; + this.unversionedName = unversionedName; + this.name = VERSIONS_PREFIX + version + '/' + unversionedName; + } + this.time = time; + } + protected AbstractJarEntry(final String name, final long time) { this.name = name; this.time = time; @@ -55,6 +89,8 @@ protected AbstractJarEntry(final String name, final long time) { /** * Gets the fully-qualified name of the jar entry. * + *

This method does not have any special handling for multi-release jars.

+ * * @return The name */ public final String getName() { @@ -70,6 +106,48 @@ public final long getTime() { return this.time; } + /** + * Get the name of this entry, as it will be seen by a multi-release-aware + * jar handler. + * + *

When a file path is in the {@code META-INF/versions/} folder but does + * not provide a valid multi-release version, it will be treated as if it + * were an ordinary, un-versioned resource.

+ * + *

This will always handle multi-release paths, even when the + * {@code Multi-Release} manifest attribute is set to false.

+ * + * @return the full entry name, without any version prefix + */ + public final String getUnversionedName() { + if (this.unversionedName != null) return this.unversionedName; + + if (!this.name.startsWith(VERSIONS_PREFIX)) { + return this.unversionedName = this.name; + } + // / + final String trimmed = this.name.substring(VERSIONS_PREFIX.length()); + final int divider = trimmed.indexOf('/'); + if (divider == -1) { // malformed, ignore + return this.unversionedName = this.name; + } + + final String version = trimmed.substring(0, divider); + final String unversioned = trimmed.substring(divider + 1); + try { + if (!unversioned.startsWith(META_INF)) { // Files already within META-INF cannot be versioned + final int parsedVersion = Integer.parseInt(version); + if (parsedVersion >= 0) { + this.version = parsedVersion; + return this.unversionedName = unversioned; + } + } + } catch (final NumberFormatException ignored) { // invalid integer, treat as unversioned + // fall through + } + return this.unversionedName = this.name; + } + /** * Gets the package that contains the jar entry, an empty * string if in the root package. @@ -78,9 +156,10 @@ public final long getTime() { */ public final String getPackage() { if (this.packageName != null) return this.packageName; - final int index = this.name.lastIndexOf('/'); + final String name = this.getUnversionedName(); + final int index = name.lastIndexOf('/'); if (index == -1) return this.packageName = ""; - return this.packageName = this.name.substring(0, index); + return this.packageName = name.substring(0, index); } /** @@ -92,12 +171,28 @@ public final String getSimpleName() { if (this.simpleName != null) return this.simpleName; final int packageLength = this.getPackage().isEmpty() ? -1 : this.getPackage().length(); final int extensionLength = this.getExtension().isEmpty() ? -1 : this.getExtension().length(); - return this.simpleName = this.name.substring( + final String name = this.getUnversionedName(); + return this.simpleName = name.substring( packageLength + 1, - this.name.length() - (extensionLength + 1) + name.length() - (extensionLength + 1) ); } + /** + * If this is a multi-release variant of a class file in a multi-release + * jar, the version associated with this variant. + * + * @return the version, or {@link #UNVERSIONED} if this is the base version, + * or a file that would not be interpreted as a multi-release variant + * within the version folder. + * @see #getUnversionedName() for a description of the conditions on multi-release jars + */ + public int getVersion() { + if (this.unversionedName != null) return this.version; + this.getUnversionedName(); // initialize versions + return this.version; + } + /** * Gets the extension of the jar entry. * @@ -132,9 +227,9 @@ public final void write(final JarOutputStream jos) throws IOException { /** * Processes the jar entry with the given transformer. * - * @param vistor The transformer + * @param visitor The transformer * @return The jar entry */ - public abstract AbstractJarEntry accept(final JarEntryTransformer vistor); + public abstract AbstractJarEntry accept(final JarEntryTransformer visitor); } diff --git a/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarClassEntry.java b/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarClassEntry.java index 51fdbac..3ed0049 100644 --- a/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarClassEntry.java +++ b/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarClassEntry.java @@ -42,6 +42,11 @@ public class JarClassEntry extends AbstractJarEntry { private final byte[] contents; + public JarClassEntry(final int version, final String unversionedName, final long time, final byte[] contents) { + super(version, unversionedName, time); + this.contents = contents; + } + public JarClassEntry(final String name, final long time, final byte[] contents) { super(name, time); this.contents = contents; @@ -58,8 +63,8 @@ public final byte[] getContents() { } @Override - public final JarClassEntry accept(final JarEntryTransformer vistor) { - return vistor.transform(this); + public final JarClassEntry accept(final JarEntryTransformer visitor) { + return visitor.transform(this); } } diff --git a/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarManifestEntry.java b/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarManifestEntry.java index f55f012..4f66817 100644 --- a/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarManifestEntry.java +++ b/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarManifestEntry.java @@ -78,8 +78,8 @@ public final byte[] getContents() { } @Override - public JarManifestEntry accept(final JarEntryTransformer vistor) { - return vistor.transform(this); + public JarManifestEntry accept(final JarEntryTransformer visitor) { + return visitor.transform(this); } } diff --git a/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarResourceEntry.java b/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarResourceEntry.java index 65f94ae..490bf38 100644 --- a/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarResourceEntry.java +++ b/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarResourceEntry.java @@ -42,6 +42,11 @@ public class JarResourceEntry extends AbstractJarEntry { private final byte[] contents; private String extension; + public JarResourceEntry(final int version, final String unversionedName, final long time, final byte[] contents) { + super(version, unversionedName, time); + this.contents = contents; + } + public JarResourceEntry(final String name, final long time, final byte[] contents) { super(name, time); this.contents = contents; @@ -61,8 +66,8 @@ public final byte[] getContents() { } @Override - public final JarResourceEntry accept(final JarEntryTransformer vistor) { - return vistor.transform(this); + public final JarResourceEntry accept(final JarEntryTransformer visitor) { + return visitor.transform(this); } } diff --git a/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarServiceProviderConfigurationEntry.java b/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarServiceProviderConfigurationEntry.java index d3ebb96..51fb92c 100644 --- a/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarServiceProviderConfigurationEntry.java +++ b/bombe-jar/src/main/java/org/cadixdev/bombe/jar/JarServiceProviderConfigurationEntry.java @@ -79,8 +79,8 @@ public final byte[] getContents() { } @Override - public final JarServiceProviderConfigurationEntry accept(final JarEntryTransformer vistor) { - return vistor.transform(this); + public final JarServiceProviderConfigurationEntry accept(final JarEntryTransformer visitor) { + return visitor.transform(this); } } diff --git a/bombe-jar/src/main/java/org/cadixdev/bombe/jar/asm/JarEntryRemappingTransformer.java b/bombe-jar/src/main/java/org/cadixdev/bombe/jar/asm/JarEntryRemappingTransformer.java index 9b9e96a..777ea45 100644 --- a/bombe-jar/src/main/java/org/cadixdev/bombe/jar/asm/JarEntryRemappingTransformer.java +++ b/bombe-jar/src/main/java/org/cadixdev/bombe/jar/asm/JarEntryRemappingTransformer.java @@ -85,9 +85,9 @@ public JarClassEntry transform(final JarClassEntry entry) { ), 0); // Create the jar entry - final String originalName = entry.getName().substring(0, entry.getName().length() - ".class".length()); + final String originalName = entry.getUnversionedName().substring(0, entry.getUnversionedName().length() - ".class".length()); final String name = this.remapper.map(originalName) + ".class"; - return new JarClassEntry(name, entry.getTime(), writer.toByteArray()); + return new JarClassEntry(entry.getVersion(), name, entry.getTime(), writer.toByteArray()); } @Override diff --git a/bombe-jar/src/test/groovy/org/cadixdev/bombe/jar/test/JarEntrySpec.groovy b/bombe-jar/src/test/groovy/org/cadixdev/bombe/jar/test/JarEntrySpec.groovy index e682c63..e1c7904 100644 --- a/bombe-jar/src/test/groovy/org/cadixdev/bombe/jar/test/JarEntrySpec.groovy +++ b/bombe-jar/src/test/groovy/org/cadixdev/bombe/jar/test/JarEntrySpec.groovy @@ -31,6 +31,7 @@ package org.cadixdev.bombe.jar.test import org.cadixdev.bombe.jar.AbstractJarEntry +import org.cadixdev.bombe.jar.JarClassEntry import org.cadixdev.bombe.jar.JarResourceEntry import spock.lang.Specification @@ -41,6 +42,10 @@ class JarEntrySpec extends Specification { private static final AbstractJarEntry PACKAGED_ENTRY = new JarResourceEntry("pack/beep.boop", 0, null) private static final AbstractJarEntry ROOT_ENTRY = new JarResourceEntry("beep.boop", 0, null) + private static final AbstractJarEntry VERSION_BY_PATH = new JarClassEntry("META-INF/versions/9/module-info.class", 0, null) + private static final AbstractJarEntry VERSION_EXPLICIT = new JarClassEntry(11, "pack/a/b.class", 0, null) + private static final AbstractJarEntry VERSION_MALFORMED = new JarClassEntry("META-INF/versions/ab/module-info.class", 0, null) + private static final AbstractJarEntry VERSION_UNVERSIONABLE = new JarClassEntry("META-INF/versions/14/META-INF/services/a.b\$Provider", 0, null) def "reads name correctly"(final AbstractJarEntry entry, final String packageName, @@ -57,4 +62,22 @@ class JarEntrySpec extends Specification { ROOT_ENTRY | '' | 'beep' | 'boop' } + def "handles multirelease paths correctly"(final AbstractJarEntry entry, + final String fullName, + final int version, + final String name) { + expect: + entry.name == fullName + entry.version == version + entry.unversionedName == name + + where: + entry | fullName | version | name + PACKAGED_ENTRY | "pack/beep.boop" | AbstractJarEntry.UNVERSIONED | "pack/beep.boop" + VERSION_BY_PATH | "META-INF/versions/9/module-info.class" | 9 | "module-info.class" + VERSION_EXPLICIT | "META-INF/versions/11/pack/a/b.class" | 11 | "pack/a/b.class" + VERSION_MALFORMED | "META-INF/versions/ab/module-info.class" | AbstractJarEntry.UNVERSIONED | "META-INF/versions/ab/module-info.class" + VERSION_UNVERSIONABLE | "META-INF/versions/14/META-INF/services/a.b\$Provider" | AbstractJarEntry.UNVERSIONED | "META-INF/versions/14/META-INF/services/a.b\$Provider" + } + } diff --git a/bombe-jar/src/test/groovy/org/cadixdev/bombe/jar/test/asm/JarEntryRemappingTransformerSpec.groovy b/bombe-jar/src/test/groovy/org/cadixdev/bombe/jar/test/asm/JarEntryRemappingTransformerSpec.groovy index c7e4298..fa1ebdc 100644 --- a/bombe-jar/src/test/groovy/org/cadixdev/bombe/jar/test/asm/JarEntryRemappingTransformerSpec.groovy +++ b/bombe-jar/src/test/groovy/org/cadixdev/bombe/jar/test/asm/JarEntryRemappingTransformerSpec.groovy @@ -80,6 +80,28 @@ class JarEntryRemappingTransformerSpec extends Specification { node.name == 'pkg/Demo' } + def "remaps multi-release class"() { + given: + // Create a test class + def obf = new ClassWriter(0) + obf.visit(Opcodes.V9, Opcodes.ACC_PUBLIC, 'a', null, 'java/lang/Object', null) + + // Run it through the transformer + def entry = TRANSFORMER.transform(new JarClassEntry('META-INF/versions/9/a.class', 0, obf.toByteArray())) + + // Use a ClassNode for convenience + def node = new ClassNode() + def reader = new ClassReader(entry.contents) + reader.accept(node, 0) + + expect: + entry.name == 'META-INF/versions/9/pkg/Demo.class' + entry.version == 9 + entry.unversionedName == 'pkg/Demo.class' + node.name == 'pkg/Demo' + + } + def "remaps manifest"() { given: // Create a test Manifest From 5f6fa891dde79998569119d7cd9352bb597e7f80 Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Sun, 29 Aug 2021 23:21:03 +0100 Subject: [PATCH 19/21] 0.5.0: Begin changelog --- changelogs/0.5.0.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelogs/0.5.0.md diff --git a/changelogs/0.5.0.md b/changelogs/0.5.0.md new file mode 100644 index 0000000..76c613a --- /dev/null +++ b/changelogs/0.5.0.md @@ -0,0 +1,5 @@ +Bombe 0.5.0 +=== + +Bombe 0.5.0 is largely a maintenance release, cleaning up the Bombe codebase and +preparing it for newer Java modules. From b4dc52c923872279aa0c2ea9acaca6add1017465 Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Sun, 29 Aug 2021 23:53:56 +0100 Subject: [PATCH 20/21] GH-17 Prevent TypeReader from erroneously reading faulty objects --- .../java/org/cadixdev/bombe/type/TypeReader.java | 2 ++ .../org/cadixdev/bombe/test/type/TypeSpec.groovy | 13 +++++++++++++ changelogs/0.5.0.md | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/bombe/src/main/java/org/cadixdev/bombe/type/TypeReader.java b/bombe/src/main/java/org/cadixdev/bombe/type/TypeReader.java index 5d331b3..b78a993 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/type/TypeReader.java +++ b/bombe/src/main/java/org/cadixdev/bombe/type/TypeReader.java @@ -122,6 +122,8 @@ public BaseType readBaseType() { */ public ObjectType readObjectType() { final int start = this.index(); + + if (this.peek() != 'L') throw new IllegalStateException("Incomplete descriptor provided!"); this.advance(); while (this.available() && this.peek() != ';') { diff --git a/bombe/src/test/groovy/org/cadixdev/bombe/test/type/TypeSpec.groovy b/bombe/src/test/groovy/org/cadixdev/bombe/test/type/TypeSpec.groovy index 07856f5..438f942 100644 --- a/bombe/src/test/groovy/org/cadixdev/bombe/test/type/TypeSpec.groovy +++ b/bombe/src/test/groovy/org/cadixdev/bombe/test/type/TypeSpec.groovy @@ -35,6 +35,7 @@ import org.cadixdev.bombe.type.BaseType import org.cadixdev.bombe.type.FieldType import org.cadixdev.bombe.type.ObjectType import org.cadixdev.bombe.type.Type +import org.cadixdev.bombe.type.TypeReader import org.cadixdev.bombe.type.VoidType import spock.lang.Specification @@ -74,6 +75,18 @@ class TypeSpec extends Specification { 'Lorg/cadixdev/demo/Test$Inner;' | _ } + def "throw on invalid object type"(final String raw) { + when: + new TypeReader(raw).readObjectType() + + then: + thrown(IllegalStateException) + + where: + raw | _ + 'Cjava/lang/String;' | _ + } + def "reads base type"(final String raw, final BaseType expected) { given: def type = Type.of(raw) diff --git a/changelogs/0.5.0.md b/changelogs/0.5.0.md index 35b064e..8c1880b 100644 --- a/changelogs/0.5.0.md +++ b/changelogs/0.5.0.md @@ -7,3 +7,8 @@ preparing it for newer Java modules. ## Improvements - Handling for multi-release JAR files +- Improved the robustness of reading descriptors + - Introduced a reader for signatures + - [GH-17] Prevent TypeReader reading invalid object descriptors + +[GH-17]: https://github.com/CadixDev/Bombe/issues/17 From 446e809ffce194eb70ae3f3f9bb7db4af63bf3de Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Sun, 29 Aug 2021 23:56:13 +0100 Subject: [PATCH 21/21] Prevent TypeReader from throwing an exception when testing for one --- bombe/src/main/java/org/cadixdev/bombe/type/TypeReader.java | 2 +- .../test/groovy/org/cadixdev/bombe/test/type/TypeSpec.groovy | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/bombe/src/main/java/org/cadixdev/bombe/type/TypeReader.java b/bombe/src/main/java/org/cadixdev/bombe/type/TypeReader.java index b78a993..254de71 100644 --- a/bombe/src/main/java/org/cadixdev/bombe/type/TypeReader.java +++ b/bombe/src/main/java/org/cadixdev/bombe/type/TypeReader.java @@ -130,7 +130,7 @@ public ObjectType readObjectType() { this.advance(); } - if (this.peek() != ';') throw new IllegalStateException("Incomplete descriptor provided!"); + if (!this.available() || this.peek() != ';') throw new IllegalStateException("Incomplete descriptor provided!"); this.advance(); return new ObjectType(this.substring(start + 1, this.index() - 1)); diff --git a/bombe/src/test/groovy/org/cadixdev/bombe/test/type/TypeSpec.groovy b/bombe/src/test/groovy/org/cadixdev/bombe/test/type/TypeSpec.groovy index 438f942..fcb8190 100644 --- a/bombe/src/test/groovy/org/cadixdev/bombe/test/type/TypeSpec.groovy +++ b/bombe/src/test/groovy/org/cadixdev/bombe/test/type/TypeSpec.groovy @@ -84,6 +84,7 @@ class TypeSpec extends Specification { where: raw | _ + 'Ljava/lang/String' | _ 'Cjava/lang/String;' | _ }