Skip to content

Commit

Permalink
Add test for CVE-2022-36944
Browse files Browse the repository at this point in the history
Test is currently broken, as `ReflectUtil` doesn't exist in this repo
  • Loading branch information
NthPortal committed Nov 10, 2022
1 parent e4ea3ab commit aea4fd6
Showing 1 changed file with 72 additions and 0 deletions.
72 changes: 72 additions & 0 deletions compat/src/test/scala/test/scala/collection/LazyListTest.scala
Expand Up @@ -22,6 +22,74 @@ import scala.collection.mutable.{Builder, ListBuffer}
import scala.util.Try

class LazyListTest {

@Test
def serialization(): Unit = {
import java.io._

def serialize(obj: AnyRef): Array[Byte] = {
val buffer = new ByteArrayOutputStream
val out = new ObjectOutputStream(buffer)
out.writeObject(obj)
buffer.toByteArray
}

def deserialize(a: Array[Byte]): AnyRef = {
val in = new ObjectInputStream(new ByteArrayInputStream(a))
in.readObject
}

def serializeDeserialize[T <: AnyRef](obj: T) = deserialize(serialize(obj)).asInstanceOf[T]

val l = LazyList.from(10)

val ld1 = serializeDeserialize(l)
assertEquals(l.take(10).toList, ld1.take(10).toList)

l.tail.head
val ld2 = serializeDeserialize(l)
assertEquals(l.take(10).toList, ld2.take(10).toList)

LazyListTest.serializationForceCount = 0
val u = LazyList.from(10).map(x => { LazyListTest.serializationForceCount += 1; x })

@unused def printDiff(): Unit = {
val a = serialize(u)
// TODO: replace with implementation of `getFieldAccessible`, since it's private to the scala/scala repo
ReflectUtil.getFieldAccessible[LazyList[_]]("scala$collection$immutable$LazyList$$stateEvaluated").setBoolean(u, true)
val b = serialize(u)
val i = a.zip(b).indexWhere(p => p._1 != p._2)
println("difference: ")
println(s"val from = ${a.slice(i - 10, i + 10).mkString("List[Byte](", ", ", ")")}")
println(s"val to = ${b.slice(i - 10, i + 10).mkString("List[Byte](", ", ", ")")}")
}

// to update this test, comment-out `LazyList.writeReplace` and run `printDiff`
// printDiff()

val from = List[Byte](83, 116, 97, 116, 101, 59, 120, 112, 0, 0, 0, 115, 114, 0, 33, 106, 97, 118, 97, 46)
val to = List[Byte](83, 116, 97, 116, 101, 59, 120, 112, 0, 0, 1, 115, 114, 0, 33, 106, 97, 118, 97, 46)

assertEquals(LazyListTest.serializationForceCount, 0)

u.head
assertEquals(LazyListTest.serializationForceCount, 1)

val data = serialize(u)
var i = data.indexOfSlice(from)
to.foreach(x => {data(i) = x; i += 1})

val ud1 = deserialize(data).asInstanceOf[LazyList[Int]]

// this check failed before scala/scala#10118, deserialization triggered evaluation
assertEquals(LazyListTest.serializationForceCount, 1)

ud1.tail.head
assertEquals(LazyListTest.serializationForceCount, 2)

u.tail.head
assertEquals(LazyListTest.serializationForceCount, 3)
}

@Test
def t6727_and_t6440_and_8627(): Unit = {
Expand Down Expand Up @@ -403,3 +471,7 @@ class LazyListTest {
assertEquals(1, count)
}
}

object LazyListTest {
var serializationForceCount = 0
}

0 comments on commit aea4fd6

Please sign in to comment.