Skip to content
This repository was archived by the owner on Feb 20, 2019. It is now read-only.
This repository was archived by the owner on Feb 20, 2019. It is now read-only.

Deserialization in incorrect type #448

Description

@pkhamutou

Hello, could you explain me why pickling is able to deserialize in incorrect type, without any errors/warning? Or I'm doing something wrong?

"org.scala-lang.modules" %% "scala-pickling" % "0.10.1",
scalaVersion := "2.11.8"
import scala.pickling.Defaults._
import scala.pickling.binary._

object TestApp extends App {

  final case class SimpleType(str: String)
  final case class MoreComplex(str: String, xs: Seq[Int], st: SimpleType)
  final case class LessComplex(str: String, d: Double)

  val simple = SimpleType("simple type")
  val mcomplex = MoreComplex("more complex", Seq(1, 2, 3), simple)
  val lcomplex = LessComplex("less complex", 1994.23)

  println("\nMust be OK:")

  test(simple.pickle.value)("simple") // SimpleType:  SimpleType(simple type)
  test(mcomplex.pickle.value)("more") // MoreComplex: MoreComplex(more complex,List(1, 2, 3),SimpleType(simple type))
  test(lcomplex.pickle.value)("less") // LessComplex: LessComplex(less complex,1994.23)

  println("\nMust fail:")

  test(mcomplex.pickle.value)("less")   // LessComplex: LessComplex(more complex,6.6738327668E-313)
  test(mcomplex.pickle.value)("simple") // SimpleType:  SimpleType(more complex)
  test(lcomplex.pickle.value)("simple") // SimpleType:  SimpleType(less complex)
  // test(simple.pickle.value)("less") - java.lang.ArrayIndexOutOfBoundsException: 37

  class T1(str: String) {
    override def toString: String = s"T1($str)"
  }

  class T2(str: String, i: Int) {
    override def toString: String = s"T2($str,$i)"
  }

  val t1 = new T1("Hey")
  val t2 = new T2("Hello",3)

  println("\nNot a case class:")

  test(t1.pickle.value)("T1") // T1: T1(Hey)
  test(t1.pickle.value)("T2") // T2: T1(Hey)
  test(t2.pickle.value)("T1") // T1: T2(Hello,3)
  test(t2.pickle.value)("T2") // T2: T2(Hello,3)

  def test(ab: Array[Byte])(name: String): Unit = name match {
    case "simple" =>  println("SimpleType:  " + ab.unpickle[SimpleType])
    case "more"   =>  println("MoreComplex: " + ab.unpickle[MoreComplex])
    case "less"   =>  println("LessComplex: " + ab.unpickle[LessComplex])
    case "T1"     =>  println("T1: " + ab.unpickle[T1])
    case "T2"     =>  println("T2: " + ab.unpickle[T2])
  }
}

Output:

Must be OK:
SimpleType:  SimpleType(simple type)
MoreComplex: MoreComplex(more complex,List(1, 2, 3),SimpleType(simple type))
LessComplex: LessComplex(less complex,1994.23)

Must fail:
LessComplex: LessComplex(more complex,6.6738327668E-313)
SimpleType:  SimpleType(more complex)
SimpleType:  SimpleType(less complex)

Not a case class:
T1: T1(Hey)
T2: T1(Hey)
T1: T2(Hello,3)
T2: T2(Hello,3)

So as you can see it is possible to deserialize MoreComplex or LessComplex into SimpleType but not other way around. So how can I be sure that I unpickle it in a proper type?

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions