Skip to content

Commit

Permalink
Make ConfigurationCacheHackList safe from Java's object serializati…
Browse files Browse the repository at this point in the history
…on foibles.
  • Loading branch information
nedtwigg committed Jan 3, 2025
1 parent c8d5cee commit 71d49b0
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2024 DiffPlug
* Copyright 2024-2025 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,6 +15,8 @@
*/
package com.diffplug.spotless;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
Expand Down Expand Up @@ -48,8 +50,27 @@
*/
public class ConfigurationCacheHackList implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private final boolean optimizeForEquality;
private final ArrayList<Object> backingList = new ArrayList<>();
private boolean optimizeForEquality;
public ArrayList<Object> backingList = new ArrayList<>();

private void writeObject(java.io.ObjectOutputStream out) throws IOException {
out.writeBoolean(optimizeForEquality);
out.writeInt(backingList.size());
for (Object obj : backingList) {
// if write out the list on its own, we'll get java's non-deterministic object-graph serialization
// by writing each object to raw bytes independently, we avoid this
out.writeObject(LazyForwardingEquality.toBytes((Serializable) obj));
}
}

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
optimizeForEquality = in.readBoolean();
backingList = new ArrayList<>();
int size = in.readInt();
for (int i = 0; i < size; i++) {
backingList.add(LazyForwardingEquality.fromBytes((byte[]) in.readObject()));
}
}

public static ConfigurationCacheHackList forEquality() {
return new ConfigurationCacheHackList(true);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2023 DiffPlug
* Copyright 2016-2025 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,6 +15,7 @@
*/
package com.diffplug.spotless;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
Expand Down Expand Up @@ -112,6 +113,15 @@ static byte[] toBytes(Serializable obj) {
return byteOutput.toByteArray();
}

static Object fromBytes(byte[] bytes) {
ByteArrayInputStream byteOutput = new ByteArrayInputStream(bytes);
try (ObjectInputStream objectOutput = new ObjectInputStream(byteOutput)) {
return objectOutput.readObject();
} catch (IOException | ClassNotFoundException e) {
throw ThrowingEx.asRuntime(e);
}
}

/** Ensures that the lazy state has been evaluated. */
public static void unlazy(Object in) {
if (in instanceof LazyForwardingEquality) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2024 DiffPlug
* Copyright 2016-2025 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2024 DiffPlug
* Copyright 2016-2025 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -98,4 +98,14 @@ public StringSelfie expectLintsOfResource(String filename, String resource) {
throw new AssertionError(e);
}
}

public StringSelfie expectLintsOfFileAndContent(String filename, String content) {
try {
File file = harness.setFile(filename).toContent(content);
LintState state = LintState.of(formatter(), file);
return StepHarness.expectLintsOf(state, formatter());
} catch (IOException e) {
throw new AssertionError(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2020-2024 DiffPlug
* Copyright 2020-2025 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -24,6 +24,7 @@
import com.diffplug.spotless.FormatterStep;
import com.diffplug.spotless.ResourceHarness;
import com.diffplug.spotless.StepHarness;
import com.diffplug.spotless.StepHarnessWithFile;

class FenceStepTest extends ResourceHarness {
@Test
Expand Down Expand Up @@ -85,7 +86,7 @@ void broken() {
FormatterStep fence = FenceStep.named("fence").openClose("spotless:off", "spotless:on")
.preserveWithin(Arrays.asList(ReplaceStep.create("replace", "spotless:on", "REMOVED")));
// this fails because uppercase turns spotless:off into SPOTLESS:OFF, etc
StepHarness.forStep(fence).expectLintsOf(StringPrinter.buildStringFromLines("A B C",
StepHarnessWithFile.forStep(this, fence).expectLintsOfFileAndContent("README.md", StringPrinter.buildStringFromLines("A B C",
"spotless:off",
"D E F",
"spotless:on",
Expand Down

0 comments on commit 71d49b0

Please sign in to comment.