Skip to content

Commit

Permalink
Merge branch 'hotfix-0.4.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
jamierocks committed May 26, 2020
2 parents cb6c448 + 70e5e5b commit 709d4c6
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Copyright (c) 2018, Jamie Mansfield <https://jamiemansfield.me/>
* 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.asm.test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.cadixdev.bombe.asm.jar.JarEntryRemappingTransformer;
import org.cadixdev.bombe.jar.JarClassEntry;
import org.cadixdev.bombe.jar.JarManifestEntry;
import org.cadixdev.bombe.jar.JarServiceProviderConfigurationEntry;
import org.cadixdev.bombe.jar.ServiceProviderConfiguration;
import org.junit.jupiter.api.Test;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.Remapper;
import org.objectweb.asm.tree.ClassNode;

import java.io.IOException;
import java.util.Collections;
import java.util.jar.Manifest;

/**
* Unit tests pertaining to {@link JarEntryRemappingTransformer}.
*/
public final class JarEntryRemappingTransformerTests {

private static final Remapper REMAPPER = new Remapper() {
@Override
public String map(final String internalName) {
if ("a".equals(internalName)) return "pkg/Demo";
if ("b".equals(internalName)) return "pkg/DemoTwo";
return internalName;
}
};
private static final JarEntryRemappingTransformer TRANSFORMER =
new JarEntryRemappingTransformer(REMAPPER);

@Test
public void remapsClasses() {
// Create a test class
final ClassWriter obf = new ClassWriter(0);
obf.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "a", null, "java/lang/Object", null);

// Run it through the transformer
final JarClassEntry entry = TRANSFORMER.transform(new JarClassEntry("a.class", 0, obf.toByteArray()));
assertEquals("pkg/Demo.class", entry.getName());

// Verify the contents
final ClassNode node = new ClassNode();
final ClassReader reader = new ClassReader(entry.getContents());
reader.accept(node, 0);
assertEquals("pkg/Demo", node.name);
}

@Test
public void remapsMainClass() {
final Manifest obfManifest = new Manifest();
{
obfManifest.getMainAttributes().putValue("Manifest-Version", "1.0");
obfManifest.getMainAttributes().putValue("Main-Class", "a");
}

final JarManifestEntry manifestEntry = TRANSFORMER.transform(new JarManifestEntry(0, obfManifest));
final Manifest deobfManifest = manifestEntry.getManifest();
assertEquals("pkg.Demo", deobfManifest.getMainAttributes().getValue("Main-Class"));
}

@Test
public void remapsSimpleManifest() {
final Manifest obfManifest = new Manifest();
{
obfManifest.getMainAttributes().putValue("Manifest-Version", "1.0");
}

TRANSFORMER.transform(new JarManifestEntry(0, obfManifest));
}

@Test
public void remapsConfig() {
final ServiceProviderConfiguration obfConfig = new ServiceProviderConfiguration(
"a",
Collections.singletonList("b")
);
final ServiceProviderConfiguration deobfConfig =
TRANSFORMER.transform(new JarServiceProviderConfigurationEntry(0, obfConfig)).getConfig();
assertEquals("pkg.Demo", deobfConfig.getService());
assertEquals(1, deobfConfig.getProviders().size());
assertTrue(deobfConfig.getProviders().contains("pkg.DemoTwo"), "Provider not present!");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@

import java.util.List;
import java.util.function.BiFunction;
import java.util.jar.Attributes;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -84,14 +85,17 @@ public JarClassEntry transform(final JarClassEntry entry) {

@Override
public JarManifestEntry transform(final JarManifestEntry entry) {
// Remap the Main-Class attribute
final String mainClassObf = entry.getManifest().getMainAttributes().getValue("Main-Class")
.replace('.', '/');
final String mainClassDeobf = this.remapper.map(mainClassObf)
.replace('/', '.');
// 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")
.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 need'nt create a new entry \o/
entry.getManifest().getMainAttributes().putValue("Main-Class", mainClassDeobf);
return entry;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,18 @@ class JarEntryRemappingTransformerSpec extends Specification {
deobf.mainAttributes[name('Main-Class')] == 'pkg.Demo'
}

def "remaps simple manifest"() {
given:
// Create a test Manifest
def obf = new Manifest()
obf.with {
mainAttributes[name('Manifest-Version')] = '1.0'
}

// Run it through the transformer
TRANSFORMER.transform(new JarManifestEntry(0, obf)).manifest
}

def "remaps service config"() {
given:
// Create a test service config
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ subprojects {

group = 'org.cadixdev'
archivesBaseName = project.name.toLowerCase()
version = '0.4.0'
version = '0.4.1'

repositories {
mavenCentral()
Expand Down
9 changes: 9 additions & 0 deletions changelogs/0.3.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Bombe 0.3.2
===========

Bombe 0.3.2 resolves a critical bug with `JarEntryRemappingTransformer` where it
would crash given a manifest with no `Main-Class`.

As Bombe 0.3.x is still in use by the latest version of Lorenz and Atlas, and
used in software running today - this is why a further release to 0.3 is being
made.
7 changes: 7 additions & 0 deletions changelogs/0.4.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Bombe 0.4.1
===========

Bombe 0.4.1 resolves a critical bug with `JarEntryRemappingTransformer` where it
would crash given a manifest with no `Main-Class`.

An equivalent change was made in Bombe 0.3.2.

0 comments on commit 709d4c6

Please sign in to comment.