Repository: googleapis/google-http-java-client
Pull request #2043 (2024-12-04 18:42:40)

fix: NPE if response entity is null


Patch:
diff --git a/google-http-client-apache-v5/src/main/java/com/google/api/client/http/apache/v5/Apache5HttpResponse.java b/google-http-client-apache-v5/src/main/java/com/google/api/client/http/apache/v5/Apache5HttpResponse.java
index 1574c8c8..ae3c2ffb 100644
--- a/google-http-client-apache-v5/src/main/java/com/google/api/client/http/apache/v5/Apache5HttpResponse.java
+++ b/google-http-client-apache-v5/src/main/java/com/google/api/client/http/apache/v5/Apache5HttpResponse.java
@@ -46,7 +46,8 @@ final class Apache5HttpResponse extends LowLevelHttpResponse {
 
   @Override
   public InputStream getContent() throws IOException {
-    return new Apache5ResponseContent(entity.getContent(), response);
+    InputStream content = entity == null ? null : entity.getContent();
+    return new Apache5ResponseContent(content, response);
   }
 
   @Override
diff --git a/google-http-client-apache-v5/src/main/java/com/google/api/client/http/apache/v5/Apache5ResponseContent.java b/google-http-client-apache-v5/src/main/java/com/google/api/client/http/apache/v5/Apache5ResponseContent.java
index c2d3091d..dfb6da8a 100644
--- a/google-http-client-apache-v5/src/main/java/com/google/api/client/http/apache/v5/Apache5ResponseContent.java
+++ b/google-http-client-apache-v5/src/main/java/com/google/api/client/http/apache/v5/Apache5ResponseContent.java
@@ -59,8 +59,12 @@ public class Apache5ResponseContent extends InputStream {
 
   @Override
   public void close() throws IOException {
-    wrappedStream.close();
-    response.close();
+    if (wrappedStream != null) {
+      wrappedStream.close();
+    }
+    if (response != null) {
+      response.close();
+    }
   }
 
   @Override


Test patch:
diff --git a/google-http-client-apache-v5/src/test/java/com/google/api/client/http/apache/v5/Apache5HttpResponseTest.java b/google-http-client-apache-v5/src/test/java/com/google/api/client/http/apache/v5/Apache5HttpResponseTest.java
new file mode 100644
index 00000000..d2712b35
--- /dev/null
+++ b/google-http-client-apache-v5/src/test/java/com/google/api/client/http/apache/v5/Apache5HttpResponseTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.api.client.http.apache.v5;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.InputStream;
+import org.apache.hc.client5.http.classic.methods.HttpPost;
+import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
+import org.junit.Test;
+
+public class Apache5HttpResponseTest {
+  @Test
+  public void testNullContent() throws Exception {
+    HttpUriRequestBase base = new HttpPost("http://www.google.com");
+    MockClassicHttpResponse mockResponse = new MockClassicHttpResponse();
+    mockResponse.setEntity(null);
+    Apache5HttpResponse response = new Apache5HttpResponse(base, mockResponse);
+
+    InputStream content = response.getContent();
+
+    assertNotNull(content);
+  }
+}
diff --git a/google-http-client-apache-v5/src/test/java/com/google/api/client/http/apache/v5/Apache5ResponseContentTest.java b/google-http-client-apache-v5/src/test/java/com/google/api/client/http/apache/v5/Apache5ResponseContentTest.java
new file mode 100644
index 00000000..ddbda0dd
--- /dev/null
+++ b/google-http-client-apache-v5/src/test/java/com/google/api/client/http/apache/v5/Apache5ResponseContentTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.api.client.http.apache.v5;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.junit.Test;
+
+public class Apache5ResponseContentTest {
+  @Test
+  public void testNullResponseContent_doesNotThrowExceptionOnClose() throws Exception {
+    Apache5ResponseContent response =
+        new Apache5ResponseContent(
+            new InputStream() {
+              @Override
+              public int read() throws IOException {
+                return 0;
+              }
+            },
+            null);
+
+    response.close();
+  }
+
+  @Test
+  public void testNullWrappedContent_doesNotThrowExceptionOnClose() throws Exception {
+    MockClassicHttpResponse mockResponse = new MockClassicHttpResponse();
+    Apache5ResponseContent response = new Apache5ResponseContent(null, mockResponse);
+
+    response.close();
+  }
+}