[HHH-16772] Generated bytecode for HibernateAccessOptimizer class is invalid and causes operand stack overflow issue

This commit is contained in:
lvydra 2024-10-02 12:44:11 +02:00 committed by Christian Beikov
parent df8745aaff
commit 8ba6d4321b
4 changed files with 70 additions and 1 deletions

View File

@ -537,7 +537,10 @@ public class BytecodeProviderImpl implements BytecodeProvider {
);
}
methodVisitor.visitInsn( Opcodes.RETURN );
return new Size( 2, instrumentedMethod.getStackSize() );
return new Size(
is64BitType( type ) ? 3 : 2,
instrumentedMethod.getStackSize()
);
}
private int getLoadOpCode(Class<?> type) {
@ -554,6 +557,10 @@ public class BytecodeProviderImpl implements BytecodeProvider {
}
return Opcodes.ALOAD;
}
private boolean is64BitType(Class<?> type) {
return type == long.class || type == double.class;
}
}
private List<ForeignPackageClassInfo> createForeignPackageClassInfos(Class<?> clazz) {

View File

@ -6,13 +6,18 @@ import static org.junit.Assert.assertNotNull;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedHashMap;
import java.util.Map;
import org.hibernate.bytecode.enhance.internal.bytebuddy.EnhancerImpl;
import org.hibernate.bytecode.enhance.spi.DefaultEnhancementContext;
import org.hibernate.bytecode.enhance.spi.EnhancementException;
import org.hibernate.bytecode.enhance.spi.Enhancer;
import org.hibernate.bytecode.spi.ByteCodeHelper;
import org.hibernate.bytecode.spi.ReflectionOptimizer;
import org.hibernate.property.access.internal.PropertyAccessStrategyFieldImpl;
import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.proxy.pojo.bytebuddy.ByteBuddyProxyHelper;
import org.hibernate.testing.orm.junit.JiraKey;
import org.junit.Test;
public class GenerateProxiesTest {
@ -43,6 +48,29 @@ public class GenerateProxiesTest {
assertNotNull( reflectionOptimizer.getInstantiationOptimizer().newInstance() );
}
@Test
@JiraKey("HHH-16772")
public void generateFastMappedSuperclassAndReflectionOptimizer() {
BytecodeProviderImpl bytecodeProvider = new BytecodeProviderImpl();
final Map<String, PropertyAccess> propertyAccessMap = new LinkedHashMap<>();
final PropertyAccessStrategyFieldImpl propertyAccessStrategy = new PropertyAccessStrategyFieldImpl();
propertyAccessMap.put(
"timestamp",
propertyAccessStrategy.buildPropertyAccess(MappedSuperclassEntity.class, "value", true )
);
ReflectionOptimizer reflectionOptimizer = bytecodeProvider.getReflectionOptimizer(
MappedSuperclassEntity.class,
propertyAccessMap
);
assertNotNull(reflectionOptimizer);
assertEquals( 1, reflectionOptimizer.getAccessOptimizer().getPropertyNames().length );
assertNotNull( reflectionOptimizer.getInstantiationOptimizer().newInstance() );
}
@Test
public void generateEnhancedClass() throws EnhancementException, IOException {
Enhancer enhancer = new EnhancerImpl( new DefaultEnhancementContext(), new ByteBuddyState() );

View File

@ -0,0 +1,15 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.bytecode.internal.bytebuddy;
import jakarta.persistence.Entity;
import org.hibernate.bytecode.internal.bytebuddy.mappedsuperclass.BaseMappedSuperclass;
@Entity
public class MappedSuperclassEntity extends BaseMappedSuperclass {
}

View File

@ -0,0 +1,19 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.bytecode.internal.bytebuddy.mappedsuperclass;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
@MappedSuperclass
public abstract class BaseMappedSuperclass {
@Id
protected Long id;
protected long value;
}