Skip to content

Commit

Permalink
Merge pull request #18415 from smowton/smowton/feature/exclude-writer…
Browse files Browse the repository at this point in the history
…eplace-from-serializable-checks

Java: exclude `writeReplace`-defining classes from `Serializable` check
  • Loading branch information
smowton authored Jan 7, 2025
2 parents 148b78a + dd0012e commit 1761721
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ where
c.hasNoParameters() and
not c.isPrivate()
) and
// Assume if an object replaces itself prior to serialization,
// then it is unlikely to be directly deserialized.
// That means it won't need to comply with default serialization rules,
// such as non-serializable super-classes having a no-argument constructor.
not exists(Method m |
m = serial.getAMethod() and
m.hasName("writeReplace") and
m.getReturnType() instanceof TypeObject and
m.hasNoParameters()
) and
serial.fromSource()
select serial,
"This class is serializable, but its non-serializable " +
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: fix
---
* Classes that define a `writeReplace` method are no longer flagged by the `java/missing-no-arg-constructor-on-serializable` query on the assumption they are unlikely to be deserialized using the default algorithm.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
| Test.java:12:7:12:7 | A | This class is serializable, but its non-serializable super-class $@ does not declare a no-argument constructor. | Test.java:4:7:4:21 | NonSerializable | NonSerializable |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Likely Bugs/Serialization/MissingVoidConstructorsOnSerializable.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import java.io.ObjectStreamException;
import java.io.Serializable;

class NonSerializable {

// Has no default constructor
public NonSerializable(int x) { }

}

// BAD: Serializable but its parent cannot be instantiated
class A extends NonSerializable implements Serializable {
public A() { super(1); }
}

// GOOD: writeReplaces itself, so unlikely to be deserialized
// according to default rules.
class B extends NonSerializable implements Serializable {
public B() { super(2); }

public Object writeReplace() throws ObjectStreamException {
return null;
}
}

0 comments on commit 1761721

Please sign in to comment.