From 8ba6d4321ba144d1398a70b9df575513ae9de187 Mon Sep 17 00:00:00 2001 From: lvydra Date: Wed, 2 Oct 2024 12:44:11 +0200 Subject: [PATCH] [HHH-16772] Generated bytecode for HibernateAccessOptimizer class is invalid and causes operand stack overflow issue --- .../bytebuddy/BytecodeProviderImpl.java | 9 +++++- .../bytebuddy/GenerateProxiesTest.java | 28 +++++++++++++++++++ .../bytebuddy/MappedSuperclassEntity.java | 15 ++++++++++ .../BaseMappedSuperclass.java | 19 +++++++++++++ 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/bytecode/internal/bytebuddy/MappedSuperclassEntity.java create mode 100644 hibernate-core/src/test/java/org/hibernate/bytecode/internal/bytebuddy/mappedsuperclass/BaseMappedSuperclass.java diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java index 0540f6f9b7..d5088c0424 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java @@ -537,7 +537,10 @@ public Size apply( ); } 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 @@ private int getLoadOpCode(Class type) { } return Opcodes.ALOAD; } + + private boolean is64BitType(Class type) { + return type == long.class || type == double.class; + } } private List createForeignPackageClassInfos(Class clazz) { diff --git a/hibernate-core/src/test/java/org/hibernate/bytecode/internal/bytebuddy/GenerateProxiesTest.java b/hibernate-core/src/test/java/org/hibernate/bytecode/internal/bytebuddy/GenerateProxiesTest.java index 7b7e52ec87..b50538855e 100644 --- a/hibernate-core/src/test/java/org/hibernate/bytecode/internal/bytebuddy/GenerateProxiesTest.java +++ b/hibernate-core/src/test/java/org/hibernate/bytecode/internal/bytebuddy/GenerateProxiesTest.java @@ -6,13 +6,18 @@ 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 void generateFastClassAndReflectionOptimizer() { assertNotNull( reflectionOptimizer.getInstantiationOptimizer().newInstance() ); } + @Test + @JiraKey("HHH-16772") + public void generateFastMappedSuperclassAndReflectionOptimizer() { + BytecodeProviderImpl bytecodeProvider = new BytecodeProviderImpl(); + final Map 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() ); diff --git a/hibernate-core/src/test/java/org/hibernate/bytecode/internal/bytebuddy/MappedSuperclassEntity.java b/hibernate-core/src/test/java/org/hibernate/bytecode/internal/bytebuddy/MappedSuperclassEntity.java new file mode 100644 index 0000000000..5b77ab9fff --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/bytecode/internal/bytebuddy/MappedSuperclassEntity.java @@ -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 . + */ +package org.hibernate.bytecode.internal.bytebuddy; + +import jakarta.persistence.Entity; +import org.hibernate.bytecode.internal.bytebuddy.mappedsuperclass.BaseMappedSuperclass; + +@Entity +public class MappedSuperclassEntity extends BaseMappedSuperclass { + +} diff --git a/hibernate-core/src/test/java/org/hibernate/bytecode/internal/bytebuddy/mappedsuperclass/BaseMappedSuperclass.java b/hibernate-core/src/test/java/org/hibernate/bytecode/internal/bytebuddy/mappedsuperclass/BaseMappedSuperclass.java new file mode 100644 index 0000000000..376a136e32 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/bytecode/internal/bytebuddy/mappedsuperclass/BaseMappedSuperclass.java @@ -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 . + */ +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; +}