Skip to content

Commit

Permalink
fix: possible NPE when HttpStorageOptions deserialized (#2153)
Browse files Browse the repository at this point in the history
Java can dedupe objects in a cyclic traversal, retryingDepsAdapter doesn't need to be transient.

b/294399427
  • Loading branch information
BenWhitehead authored Aug 3, 2023
1 parent eba8b6a commit 68ad8e7
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public class HttpStorageOptions extends StorageOptions {
private static final String DEFAULT_HOST = "https://storage.googleapis.com";

private final HttpRetryAlgorithmManager retryAlgorithmManager;
private final transient RetryDependenciesAdapter retryDepsAdapter;
private final RetryDependenciesAdapter retryDepsAdapter;

private HttpStorageOptions(Builder builder, StorageDefaults serviceDefaults) {
super(builder, serviceDefaults);
Expand Down Expand Up @@ -334,7 +334,7 @@ public ServiceRpc create(StorageOptions options) {
* We don't yet want to make HttpStorageOptions itself implement {@link RetryingDependencies} but
* we do need use it in a couple places, for those we create this adapter.
*/
private final class RetryDependenciesAdapter implements RetryingDependencies {
private final class RetryDependenciesAdapter implements RetryingDependencies, Serializable {

private RetryDependenciesAdapter() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Base64;
import java.util.Collections;
Expand Down Expand Up @@ -213,6 +215,29 @@ protected Serializable[] serializableObjects() {
}
}

@Test
public void avoidNpeHttpStorageOptions_retryDeps() throws IOException, ClassNotFoundException {
HttpStorageOptions optionsHttp1 =
StorageOptions.http()
.setProjectId("http1")
.setCredentials(NoCredentials.getInstance())
.build();

assertThat(optionsHttp1.asRetryDependencies()).isNotNull();

ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(optionsHttp1);
}

byte[] byteArray = baos.toByteArray();
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(byteArray))) {
Object o = ois.readObject();
HttpStorageOptions hso = (HttpStorageOptions) o;
assertThat(hso.asRetryDependencies()).isNotNull();
}
}

@Override
@SuppressWarnings("resource")
protected Restorable<?>[] restorableObjects() {
Expand Down

0 comments on commit 68ad8e7

Please sign in to comment.