Skip to content

Commit 39bc996

Browse files
committed
#1192 check null before use this.content
1 parent ba2db77 commit 39bc996

File tree

2 files changed

+58
-53
lines changed

2 files changed

+58
-53
lines changed

spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessHttpServletRequest.java

Lines changed: 43 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -67,24 +67,23 @@
6767
import org.springframework.util.MultiValueMap;
6868

6969
/**
70-
*
7170
* @author Oleg Zhurakousky
72-
*
7371
*/
7472
public class ServerlessHttpServletRequest implements HttpServletRequest {
7573

7674
private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
7775

7876
private static final BufferedReader EMPTY_BUFFERED_READER = new BufferedReader(new StringReader(""));
77+
private static final InputStream EMPTY_INPUT_STREAM = new ByteArrayInputStream(new byte[0]);
7978

8079
/**
8180
* Date formats as specified in the HTTP RFC.
8281
*
8382
* @see <a href="https://tools.ietf.org/html/rfc7231#section-7.1.1.1">Section
84-
* 7.1.1.1 of RFC 7231</a>
83+
* 7.1.1.1 of RFC 7231</a>
8584
*/
86-
private static final String[] DATE_FORMATS = new String[] { "EEE, dd MMM yyyy HH:mm:ss zzz",
87-
"EEE, dd-MMM-yy HH:mm:ss zzz", "EEE MMM dd HH:mm:ss yyyy" };
85+
private static final String[] DATE_FORMATS = new String[]{"EEE, dd MMM yyyy HH:mm:ss zzz",
86+
"EEE, dd-MMM-yy HH:mm:ss zzz", "EEE MMM dd HH:mm:ss yyyy"};
8887

8988
private final ServletContext servletContext;
9089

@@ -108,7 +107,9 @@ public class ServerlessHttpServletRequest implements HttpServletRequest {
108107

109108
private final Map<String, String[]> parameters = new LinkedHashMap<>(16);
110109

111-
/** List of locales in descending order. */
110+
/**
111+
* List of locales in descending order.
112+
*/
112113
private final LinkedList<Locale> locales = new LinkedList<>();
113114

114115
private boolean asyncStarted = false;
@@ -229,9 +230,9 @@ public void setContent(@Nullable byte[] content) {
229230
* Get the content of the request body as a byte array.
230231
*
231232
* @return the content as a byte array (potentially {@code null})
232-
* @since 5.0
233233
* @see #setContent(byte[])
234234
* @see #getContentAsString()
235+
* @since 5.0
235236
*/
236237
@Nullable
237238
public byte[] getContentAsByteArray() {
@@ -247,10 +248,10 @@ public byte[] getContentAsByteArray() {
247248
* set
248249
* @throws UnsupportedEncodingException if the character encoding is not
249250
* supported
250-
* @since 5.0
251251
* @see #setContent(byte[])
252252
* @see #setCharacterEncoding(String)
253253
* @see #getContentAsByteArray()
254+
* @since 5.0
254255
*/
255256
@Nullable
256257
public String getContentAsString() throws IllegalStateException, UnsupportedEncodingException {
@@ -283,7 +284,14 @@ public String getContentType() {
283284

284285
@Override
285286
public ServletInputStream getInputStream() {
286-
InputStream stream = new ByteArrayInputStream(this.content);
287+
InputStream stream;
288+
if (this.content == null) {
289+
stream = EMPTY_INPUT_STREAM;
290+
} else {
291+
stream = new ByteArrayInputStream(this.content);
292+
}
293+
294+
287295
return new ServletInputStream() {
288296

289297
boolean finished = false;
@@ -320,7 +328,7 @@ public boolean isFinished() {
320328
* name, they will be replaced.
321329
*/
322330
public void setParameter(String name, String value) {
323-
setParameter(name, new String[] { value });
331+
setParameter(name, new String[]{value});
324332
}
325333

326334
/**
@@ -344,13 +352,11 @@ public void setParameters(Map<String, ?> params) {
344352
params.forEach((key, value) -> {
345353
if (value instanceof String) {
346354
setParameter(key, (String) value);
347-
}
348-
else if (value instanceof String[]) {
355+
} else if (value instanceof String[]) {
349356
setParameter(key, (String[]) value);
350-
}
351-
else {
357+
} else {
352358
throw new IllegalArgumentException("Parameter map value must be single value " + " or array of type ["
353-
+ String.class.getName() + "]");
359+
+ String.class.getName() + "]");
354360
}
355361
});
356362
}
@@ -362,7 +368,7 @@ else if (value instanceof String[]) {
362368
* name, the given value will be added to the end of the list.
363369
*/
364370
public void addParameter(String name, @Nullable String value) {
365-
addParameter(name, new String[] { value });
371+
addParameter(name, new String[]{value});
366372
}
367373

368374
/**
@@ -379,8 +385,7 @@ public void addParameter(String name, String... values) {
379385
System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);
380386
System.arraycopy(values, 0, newArr, oldArr.length, values.length);
381387
this.parameters.put(name, newArr);
382-
}
383-
else {
388+
} else {
384389
this.parameters.put(name, values);
385390
}
386391
}
@@ -395,13 +400,11 @@ public void addParameters(Map<String, ?> params) {
395400
params.forEach((key, value) -> {
396401
if (value instanceof String) {
397402
addParameter(key, (String) value);
398-
}
399-
else if (value instanceof String[]) {
403+
} else if (value instanceof String[]) {
400404
addParameter(key, (String[]) value);
401-
}
402-
else {
405+
} else {
403406
throw new IllegalArgumentException("Parameter map value must be single value " + " or array of type ["
404-
+ String.class.getName() + "]");
407+
+ String.class.getName() + "]");
405408
}
406409
});
407410
}
@@ -477,20 +480,18 @@ public int getServerPort() {
477480
public BufferedReader getReader() throws UnsupportedEncodingException {
478481
if (this.reader != null) {
479482
return this.reader;
480-
}
481-
else if (this.inputStream != null) {
483+
} else if (this.inputStream != null) {
482484
throw new IllegalStateException(
483-
"Cannot call getReader() after getInputStream() has already been called for the current request");
485+
"Cannot call getReader() after getInputStream() has already been called for the current request");
484486
}
485487

486488
if (this.content != null) {
487489
InputStream sourceStream = new ByteArrayInputStream(this.content);
488490
Reader sourceReader = (this.characterEncoding != null)
489-
? new InputStreamReader(sourceStream, this.characterEncoding)
490-
: new InputStreamReader(sourceStream);
491+
? new InputStreamReader(sourceStream, this.characterEncoding)
492+
: new InputStreamReader(sourceStream);
491493
this.reader = new BufferedReader(sourceReader);
492-
}
493-
else {
494+
} else {
494495
this.reader = EMPTY_BUFFERED_READER;
495496
}
496497
return this.reader;
@@ -519,8 +520,7 @@ public void setAttribute(String name, @Nullable Object value) {
519520
Assert.notNull(name, "Attribute name must not be null");
520521
if (value != null) {
521522
this.attributes.put(name, value);
522-
}
523-
else {
523+
} else {
524524
this.attributes.remove(name);
525525
}
526526
}
@@ -741,18 +741,14 @@ public int getIntHeader(String name) {
741741
Object value = header.get(0);
742742
if (value instanceof Number) {
743743
return ((Number) value).intValue();
744-
}
745-
else if (value instanceof String) {
744+
} else if (value instanceof String) {
746745
return Integer.parseInt((String) value);
747-
}
748-
else if (value != null) {
746+
} else if (value != null) {
749747
throw new NumberFormatException("Value for header '" + name + "' is not a Number: " + value);
750-
}
751-
else {
748+
} else {
752749
return -1;
753750
}
754-
}
755-
else {
751+
} else {
756752
return -1;
757753
}
758754
}
@@ -764,22 +760,17 @@ public long getDateHeader(String name) {
764760
Object value = header.get(0);
765761
if (value instanceof Date) {
766762
return ((Date) value).getTime();
767-
}
768-
else if (value instanceof Number) {
763+
} else if (value instanceof Number) {
769764
return ((Number) value).longValue();
770-
}
771-
else if (value instanceof String) {
765+
} else if (value instanceof String) {
772766
return parseDateHeader(name, (String) value);
773-
}
774-
else if (value != null) {
767+
} else if (value != null) {
775768
throw new IllegalArgumentException(
776-
"Value for header '" + name + "' is not a Date, Number, or String: " + value);
777-
}
778-
else {
769+
"Value for header '" + name + "' is not a Date, Number, or String: " + value);
770+
} else {
779771
return -1L;
780772
}
781-
}
782-
else {
773+
} else {
783774
return -1;
784775
}
785776
}
@@ -790,8 +781,7 @@ private long parseDateHeader(String name, String value) {
790781
simpleDateFormat.setTimeZone(GMT);
791782
try {
792783
return simpleDateFormat.parse(value).getTime();
793-
}
794-
catch (ParseException ex) {
784+
} catch (ParseException ex) {
795785
// ignore
796786
}
797787
}

spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/serverless/web/RequestResponseTests.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,21 @@ public void validatePostWithBody() throws Exception {
149149
assertThat(pet.getName()).isNotEmpty();
150150
}
151151

152+
153+
@Test
154+
public void validatePostWithoutBody() throws Exception {
155+
ServerlessHttpServletRequest request = new ServerlessHttpServletRequest(null, "POST", "/pets/");
156+
request.setContentType("application/json");
157+
ServerlessHttpServletResponse response = new ServerlessHttpServletResponse();
158+
try {
159+
mvc.service(request, response);
160+
}catch (jakarta.servlet.ServletException e) {
161+
assertThat(e.getCause()).isNotInstanceOf(NullPointerException.class);
162+
}
163+
164+
assertThat(response.getStatus()).isEqualTo(400); // application fail because the pet is empty ;)
165+
}
166+
152167
@Test
153168
public void validatePostAsyncWithBody() throws Exception {
154169
// System.setProperty("spring.main.banner-mode", "off");

0 commit comments

Comments
 (0)