copying: fold in graph copying (shared nodes, cycles, identity-map fix), serialization rules (constructors, record canonical constructor, ObjectInputFilter), record array components, clone() as a defensive copy, two more compile-error exhibits; 24 tests
Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_017ic4b4BL3cEPHQTk2McE7C
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
[INFO] Tests run: 17, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.145 s -- in com.ankurm.copying.CopyingTest
|
||||
[INFO] Tests run: 17, Failures: 0, Errors: 0, Skipped: 0
|
||||
[INFO] Tests run: 17, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.150 s -- in com.ankurm.copying.CopyingTest
|
||||
[INFO] Tests run: 7, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.053 s -- in com.ankurm.copying.CopyingExtrasTest
|
||||
[INFO] Tests run: 24, Failures: 0, Errors: 0, Skipped: 0
|
||||
[INFO] BUILD SUCCESS
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
== 1. Diamond: root.left and root.right are the same node ==
|
||||
original : left == right : true
|
||||
copy constructor : left == right : false
|
||||
identity-map copy : left == right : true
|
||||
serialization copy : left == right : true
|
||||
|
||||
== 2. Cycle: a -> b -> a ==
|
||||
original : a.left.left == a : true
|
||||
copy constructor : StackOverflowError
|
||||
identity-map copy : copy.left.left == copy : true
|
||||
identity-map copy : copy != original : true
|
||||
@@ -0,0 +1,11 @@
|
||||
== 1. Classes: only the first non-serializable superclass constructor runs ==
|
||||
after new Child() : Child runs = 1, Parent runs = 1
|
||||
after the copy : Child runs = 1, Parent runs = 2
|
||||
|
||||
== 2. Records: the canonical constructor DOES run ==
|
||||
after new Money(..) : canonical runs = 1
|
||||
after the copy : canonical runs = 2
|
||||
|
||||
== 3. An allow-list filter on the reading side ==
|
||||
list of String and Money : [text, Money[paise=1]]
|
||||
list holding an AtomicInteger : InvalidClassException: filter status: REJECTED
|
||||
@@ -0,0 +1,9 @@
|
||||
== 1. RawPacket keeps the caller's array and returns its own ==
|
||||
after raw[0] = 99 : [99, 2, 3]
|
||||
after rp.data()[1] = 88 : [99, 88, 3]
|
||||
|
||||
== 2. Packet copies in the constructor and in the accessor ==
|
||||
after the same two writes : [1, 2, 3]
|
||||
|
||||
== 3. The generated equals() still compares the arrays by identity ==
|
||||
new Packet({1}).equals(new Packet({1})) : false
|
||||
@@ -0,0 +1,7 @@
|
||||
== 1. A 'defensive' copy made with clone() trusts the argument's own clone() ==
|
||||
clone() result is the attacker's object : true
|
||||
clone() result class : EvilDate
|
||||
|
||||
== 2. A copy made with the constructor does not ==
|
||||
new Date(getTime()) is the attacker's object : false
|
||||
new Date(getTime()) result class : Date
|
||||
@@ -0,0 +1,5 @@
|
||||
$ javac src/broken/ForgotToOverride.java
|
||||
src/broken/ForgotToOverride.java:10: error: clone() has protected access in Object
|
||||
Object copy = foo.clone();
|
||||
^
|
||||
1 error
|
||||
@@ -0,0 +1,11 @@
|
||||
$ javac src/broken/WithExpression.java
|
||||
src/broken/WithExpression.java:8: error: ';' expected
|
||||
Point q = p with { x = 10; };
|
||||
^
|
||||
src/broken/WithExpression.java:8: error: not a statement
|
||||
Point q = p with { x = 10; };
|
||||
^
|
||||
src/broken/WithExpression.java:8: error: ';' expected
|
||||
Point q = p with { x = 10; };
|
||||
^
|
||||
3 errors
|
||||
Reference in New Issue
Block a user