Skip to content
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

Initializes classes prior to instrumentation to avoid uncontrolled code execution. #2023

Merged
merged 1 commit into from Aug 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -206,6 +206,7 @@ public <T> Class<? extends T> mockClass(MockFeatures<T> features) {
Set<Class<?>> types = new HashSet<>();
types.add(features.mockedType);
types.addAll(features.interfaces);

synchronized (this) {
triggerRetransformation(types, false);
}
Expand All @@ -223,17 +224,26 @@ public synchronized void mockClassConstruction(Class<?> type) {
triggerRetransformation(Collections.singleton(type), false);
}

private static void assureInitialization(Class<?> type) {
try {
Class.forName(type.getName(), true, type.getClassLoader());
} catch (Throwable ignore) {
}
}

private <T> void triggerRetransformation(Set<Class<?>> types, boolean flat) {
Set<Class<?>> targets = new HashSet<Class<?>>();

for (Class<?> type : types) {
if (flat) {
if (!mocked.contains(type) && flatMocked.add(type)) {
assureInitialization(type);
targets.add(type);
}
} else {
do {
if (mocked.add(type)) {
assureInitialization(type);
if (!flatMocked.remove(type)) {
targets.add(type);
}
Expand Down
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2020 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockitoinline;

import org.junit.Test;
import org.mockito.Mockito;

import static junit.framework.TestCase.assertEquals;

public class InitializationTest {

@Test
public void assure_initialization_prior_to_instrumentation() {
@SuppressWarnings("unused")
SampleEnum mock = Mockito.mock(SampleEnum.class);
SampleEnum[] values = SampleEnum.values();
assertEquals("VALUE", values[0].name());
}

public enum SampleEnum {
VALUE
}
}
Expand Up @@ -7,14 +7,20 @@
import org.junit.Test;
import org.mockito.internal.configuration.plugins.Plugins;
import org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker;
import org.mockito.internal.util.reflection.ModuleMemberAccessor;

import static org.junit.Assert.*;

public class PluginTest {

@Test
public void plugin_type_should_be_inline() throws Exception {
public void mock_maker_should_be_inline() throws Exception {
assertTrue(Plugins.getMockMaker() instanceof InlineByteBuddyMockMaker);
}

@Test
public void member_accessor_should_be_module() throws Exception {
assertTrue(Plugins.getMemberAccessor() instanceof ModuleMemberAccessor);
}

}