Skip to content

Commit 8b6dcb9

Browse files
committed
Merge branch '5.3.x'
2 parents 2961426 + 83186b6 commit 8b6dcb9

File tree

5 files changed

+75
-14
lines changed

5 files changed

+75
-14
lines changed

spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.beans.PropertyDescriptor;
2323
import java.lang.reflect.Method;
2424
import java.lang.reflect.Modifier;
25+
import java.net.URL;
2526
import java.security.ProtectionDomain;
2627
import java.util.Collections;
2728
import java.util.HashSet;
@@ -292,10 +293,12 @@ private CachedIntrospectionResults(Class<?> beanClass) throws BeansException {
292293
// Only allow all name variants of Class properties
293294
continue;
294295
}
295-
if (pd.getWriteMethod() == null && pd.getPropertyType() != null &&
296-
(ClassLoader.class.isAssignableFrom(pd.getPropertyType()) ||
297-
ProtectionDomain.class.isAssignableFrom(pd.getPropertyType()))) {
298-
// Ignore ClassLoader and ProtectionDomain read-only properties - no need to bind to those
296+
if (URL.class == beanClass && "content".equals(pd.getName())) {
297+
// Only allow URL attribute introspection, not content resolution
298+
continue;
299+
}
300+
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType())) {
301+
// Ignore read-only properties such as ClassLoader - no need to bind to those
299302
continue;
300303
}
301304
if (logger.isTraceEnabled()) {
@@ -344,10 +347,8 @@ private void introspectInterfaces(Class<?> beanClass, Class<?> currClass, Set<St
344347
// GenericTypeAwarePropertyDescriptor leniently resolves a set* write method
345348
// against a declared read method, so we prefer read method descriptors here.
346349
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
347-
if (pd.getWriteMethod() == null && pd.getPropertyType() != null &&
348-
(ClassLoader.class.isAssignableFrom(pd.getPropertyType()) ||
349-
ProtectionDomain.class.isAssignableFrom(pd.getPropertyType()))) {
350-
// Ignore ClassLoader and ProtectionDomain read-only properties - no need to bind to those
350+
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType())) {
351+
// Ignore read-only properties such as ClassLoader - no need to bind to those
351352
continue;
352353
}
353354
this.propertyDescriptors.put(pd.getName(), pd);
@@ -379,8 +380,7 @@ private boolean isPlainAccessor(Method method) {
379380
if (Modifier.isStatic(method.getModifiers()) ||
380381
method.getDeclaringClass() == Object.class || method.getDeclaringClass() == Class.class ||
381382
method.getParameterCount() > 0 || method.getReturnType() == void.class ||
382-
ClassLoader.class.isAssignableFrom(method.getReturnType()) ||
383-
ProtectionDomain.class.isAssignableFrom(method.getReturnType())) {
383+
isInvalidReadOnlyPropertyType(method.getReturnType())) {
384384
return false;
385385
}
386386
try {
@@ -393,6 +393,12 @@ private boolean isPlainAccessor(Method method) {
393393
}
394394
}
395395

396+
private boolean isInvalidReadOnlyPropertyType(@Nullable Class<?> returnType) {
397+
return (returnType != null && (AutoCloseable.class.isAssignableFrom(returnType) ||
398+
ClassLoader.class.isAssignableFrom(returnType) ||
399+
ProtectionDomain.class.isAssignableFrom(returnType)));
400+
}
401+
396402

397403
BeanInfo getBeanInfo() {
398404
return this.beanInfo;

spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.springframework.beans.testfixture.beans.TestBean;
2626
import org.springframework.core.OverridingClassLoader;
2727
import org.springframework.core.io.DefaultResourceLoader;
28+
import org.springframework.core.io.UrlResource;
2829

2930
import static org.assertj.core.api.Assertions.assertThat;
3031
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -153,7 +154,7 @@ void setPropertyTypeMismatch() {
153154
}
154155

155156
@Test
156-
void propertyDescriptors() {
157+
void propertyDescriptors() throws Exception {
157158
TestBean target = new TestBean();
158159
target.setSpouse(new TestBean());
159160
BeanWrapper accessor = createAccessor(target);
@@ -182,11 +183,29 @@ void propertyDescriptors() {
182183
assertThat(accessor.isReadableProperty("class.package")).isFalse();
183184
assertThat(accessor.isReadableProperty("class.module")).isFalse();
184185
assertThat(accessor.isReadableProperty("class.classLoader")).isFalse();
186+
assertThat(accessor.isReadableProperty("class.name")).isTrue();
187+
assertThat(accessor.isReadableProperty("class.simpleName")).isTrue();
185188
assertThat(accessor.isReadableProperty("classLoader")).isTrue();
186189
assertThat(accessor.isWritableProperty("classLoader")).isTrue();
187190
OverridingClassLoader ocl = new OverridingClassLoader(getClass().getClassLoader());
188191
accessor.setPropertyValue("classLoader", ocl);
189192
assertThat(accessor.getPropertyValue("classLoader")).isSameAs(ocl);
193+
194+
accessor = createAccessor(new UrlResource("https://spring.io"));
195+
196+
assertThat(accessor.isReadableProperty("class.package")).isFalse();
197+
assertThat(accessor.isReadableProperty("class.module")).isFalse();
198+
assertThat(accessor.isReadableProperty("class.classLoader")).isFalse();
199+
assertThat(accessor.isReadableProperty("class.name")).isTrue();
200+
assertThat(accessor.isReadableProperty("class.simpleName")).isTrue();
201+
assertThat(accessor.isReadableProperty("URL.protocol")).isTrue();
202+
assertThat(accessor.isReadableProperty("URL.host")).isTrue();
203+
assertThat(accessor.isReadableProperty("URL.port")).isTrue();
204+
assertThat(accessor.isReadableProperty("URL.file")).isTrue();
205+
assertThat(accessor.isReadableProperty("URL.content")).isFalse();
206+
assertThat(accessor.isReadableProperty("inputStream")).isFalse();
207+
assertThat(accessor.isReadableProperty("filename")).isTrue();
208+
assertThat(accessor.isReadableProperty("description")).isTrue();
190209
}
191210

192211
@Test

spring-messaging/src/main/java/org/springframework/messaging/simp/broker/SimpleBrokerMessageHandler.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -306,6 +306,12 @@ protected void handleMessageInternal(Message<?> message) {
306306
else if (SimpMessageType.CONNECT.equals(messageType)) {
307307
logMessage(message);
308308
if (sessionId != null) {
309+
if (this.sessions.get(sessionId) != null) {
310+
if (logger.isWarnEnabled()) {
311+
logger.warn("Ignoring CONNECT in session " + sessionId + ". Already connected.");
312+
}
313+
return;
314+
}
309315
long[] heartbeatIn = SimpMessageHeaderAccessor.getHeartbeat(headers);
310316
long[] heartbeatOut = getHeartbeatValue();
311317
Principal user = SimpMessageHeaderAccessor.getUser(headers);

spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandler.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -552,6 +552,12 @@ else if (accessor instanceof SimpMessageHeaderAccessor) {
552552
}
553553

554554
if (StompCommand.CONNECT.equals(command) || StompCommand.STOMP.equals(command)) {
555+
if (this.connectionHandlers.get(sessionId) != null) {
556+
if (logger.isWarnEnabled()) {
557+
logger.warn("Ignoring CONNECT in session " + sessionId + ". Already connected.");
558+
}
559+
return;
560+
}
555561
if (logger.isDebugEnabled()) {
556562
logger.debug(stompAccessor.getShortLogMessage(EMPTY_PAYLOAD));
557563
}

spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandlerTests.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -260,6 +260,30 @@ void systemSubscription() {
260260
assertThat(captor.getValue()).isSameAs(message);
261261
}
262262

263+
@Test
264+
void alreadyConnected() {
265+
266+
this.brokerRelay.start();
267+
268+
Message<byte[]> connect = connectMessage("sess1", "joe");
269+
this.brokerRelay.handleMessage(connect);
270+
271+
assertThat(this.tcpClient.getSentMessages().size()).isEqualTo(2);
272+
273+
StompHeaderAccessor headers1 = this.tcpClient.getSentHeaders(0);
274+
assertThat(headers1.getCommand()).isEqualTo(StompCommand.CONNECT);
275+
assertThat(headers1.getSessionId()).isEqualTo(StompBrokerRelayMessageHandler.SYSTEM_SESSION_ID);
276+
277+
StompHeaderAccessor headers2 = this.tcpClient.getSentHeaders(1);
278+
assertThat(headers2.getCommand()).isEqualTo(StompCommand.CONNECT);
279+
assertThat(headers2.getSessionId()).isEqualTo("sess1");
280+
281+
this.brokerRelay.handleMessage(connect);
282+
283+
assertThat(this.tcpClient.getSentMessages().size()).isEqualTo(2);
284+
assertThat(this.outboundChannel.getMessages()).isEmpty();
285+
}
286+
263287
private Message<byte[]> connectMessage(String sessionId, String user) {
264288
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
265289
headers.setSessionId(sessionId);

0 commit comments

Comments
 (0)