Skip to content

Commit 1761721

Browse files
authored
Merge pull request #18415 from smowton/smowton/feature/exclude-writereplace-from-serializable-checks
Java: exclude `writeReplace`-defining classes from `Serializable` check
2 parents 148b78a + dd0012e commit 1761721

File tree

5 files changed

+40
-0
lines changed

5 files changed

+40
-0
lines changed

java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorsOnSerializable.ql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ where
2424
c.hasNoParameters() and
2525
not c.isPrivate()
2626
) and
27+
// Assume if an object replaces itself prior to serialization,
28+
// then it is unlikely to be directly deserialized.
29+
// That means it won't need to comply with default serialization rules,
30+
// such as non-serializable super-classes having a no-argument constructor.
31+
not exists(Method m |
32+
m = serial.getAMethod() and
33+
m.hasName("writeReplace") and
34+
m.getReturnType() instanceof TypeObject and
35+
m.hasNoParameters()
36+
) and
2737
serial.fromSource()
2838
select serial,
2939
"This class is serializable, but its non-serializable " +
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: fix
3+
---
4+
* 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 numberDiff line numberDiff line change
@@ -0,0 +1 @@
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 numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Likely Bugs/Serialization/MissingVoidConstructorsOnSerializable.ql
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import java.io.ObjectStreamException;
2+
import java.io.Serializable;
3+
4+
class NonSerializable {
5+
6+
// Has no default constructor
7+
public NonSerializable(int x) { }
8+
9+
}
10+
11+
// BAD: Serializable but its parent cannot be instantiated
12+
class A extends NonSerializable implements Serializable {
13+
public A() { super(1); }
14+
}
15+
16+
// GOOD: writeReplaces itself, so unlikely to be deserialized
17+
// according to default rules.
18+
class B extends NonSerializable implements Serializable {
19+
public B() { super(2); }
20+
21+
public Object writeReplace() throws ObjectStreamException {
22+
return null;
23+
}
24+
}

0 commit comments

Comments
 (0)