Scala Programming Language
  1. Scala Programming Language
  2. SI-7556

runtime reflection: corruption in unpickling when pickled data is chunked

    Details

      Description

      % head sandbox/mega-trait.scala # attached
      trait MegaTrait {
      def method0: Int = 0
      def method1: Int = 0
      def method2: Int = 0
      def method3: Int = 0
      def method4: Int = 0
      def method5: Int = 0
      def method6: Int = 0
      def method7: Int = 0
      def method8: Int = 0
        ~/code/scala tail sandbox/mega-trait.scala
      def method2991: Int = 0
      def method2992: Int = 0
      def method2993: Int = 0
      def method2994: Int = 0
      def method2995: Int = 0
      def method2996: Int = 0
      def method2997: Int = 0
      def method2998: Int = 0
      def method2999: Int = 0
      }
      
      % qbin/scalac -d sandbox/ sandbox/mega-trait.scala &&  qbin/scala -nc -classpath sandbox/ -e 'scala.reflect.runtime.universe.typeTag[MegaTrait].tpe.members'java.lang.ArrayIndexOutOfBoundsException: 958737694
      	at scala.reflect.internal.pickling.PickleBuffer.readByte(PickleBuffer.scala:104)
      	at scala.reflect.internal.pickling.PickleBuffer$$anonfun$createIndex$1.apply$mcVI$sp(PickleBuffer.scala:181)
      	at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:149)
      	at scala.reflect.internal.pickling.PickleBuffer.createIndex(PickleBuffer.scala:179)
      	at scala.reflect.internal.pickling.UnPickler$Scan.<init>(UnPickler.scala:60)
      	at scala.reflect.internal.pickling.UnPickler.unpickle(UnPickler.scala:38)
      	at scala.reflect.runtime.JavaMirrors$JavaMirror.unpickleClass(JavaMirrors.scala:592)
      	at scala.reflect.runtime.SymbolLoaders$TopClassCompleter$$anonfun$complete$1.apply$mcV$sp(SymbolLoaders.scala:35)
      	at scala.reflect.runtime.SymbolLoaders$TopClassCompleter$$anonfun$complete$1.apply(SymbolLoaders.scala:32)
      	at scala.reflect.runtime.SymbolLoaders$TopClassCompleter$$anonfun$complete$1.apply(SymbolLoaders.scala:32)
      	at scala.reflect.internal.SymbolTable.enteringPhaseNotLaterThan(SymbolTable.scala:226)
      	at scala.reflect.runtime.SymbolLoaders$TopClassCompleter.complete(SymbolLoaders.scala:32)
      	at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1319)
      	at scala.reflect.internal.Types$TypeRef.thisInfo(Types.scala:2321)
      	at scala.reflect.internal.Types$TypeRef.baseClasses(Types.scala:2326)
      	at scala.reflect.internal.Types$Type.scala$reflect$internal$Types$Type$$findMembersInternal$1(Types.scala:990)
      	at scala.reflect.internal.Types$Type.findMembers(Types.scala:1036)
      	at scala.reflect.internal.Types$Type.membersBasedOnFlags(Types.scala:624)
      	at scala.reflect.internal.Types$Type.members(Types.scala:577)
      	at scala.reflect.internal.Types$Type.members(Types.scala:256)
      	at Main$$anon$1.<init>(scalacmd6150594393612715057.scala:1)
      	at Main$.main(scalacmd6150594393612715057.scala:1)
      	at Main.main(scalacmd6150594393612715057.scala)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:597)
      	at scala.reflect.internal.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:68)
      	at scala.reflect.internal.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
      	at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:99)
      	at scala.reflect.internal.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:68)
      	at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:99)
      	at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:22)
      	at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:39)
      	at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:29)
      	at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:39)
      	at scala.tools.nsc.ScriptRunner.scala$tools$nsc$ScriptRunner$$runCompiled(ScriptRunner.scala:158)
      	at scala.tools.nsc.ScriptRunner$$anonfun$runCommand$1.apply(ScriptRunner.scala:205)
      	at scala.tools.nsc.ScriptRunner$$anonfun$runCommand$1.apply(ScriptRunner.scala:205)
      	at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1$$anonfun$apply$mcZ$sp$1.apply(ScriptRunner.scala:144)
      	at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1$$anonfun$apply$mcZ$sp$1.apply(ScriptRunner.scala:144)
      	at scala.Option.exists(Option.scala:228)
      	at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply$mcZ$sp(ScriptRunner.scala:144)
      	at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:118)
      	at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:118)
      	at scala.tools.nsc.util.package$.trackingThreads(package.scala:46)
      	at scala.tools.nsc.util.package$.waitingForThreads(package.scala:30)
      	at scala.tools.nsc.ScriptRunner.withCompiledScript(ScriptRunner.scala:117)
      	at scala.tools.nsc.ScriptRunner.runCommand(ScriptRunner.scala:205)
      	at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:92)
      	at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:103)
      	at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
      java.lang.RuntimeException: error reading Scala signature of MegaTrait: 958737694
      	at scala.reflect.internal.pickling.UnPickler.unpickle(UnPickler.scala:46)
      	at scala.reflect.runtime.JavaMirrors$JavaMirror.unpickleClass(JavaMirrors.scala:592)
      

      During unpickling, the var readIndex is mutated thusly:

      // (old, new)
      (57432,57433)
      (57433,57434)
      (57434,57435)
      (57435,57436)
      (57436,57437)
      (57437,958737694)
      

      From JavaMirrors

                  loadBytes[Array[String]]("scala.reflect.ScalaLongSignature") match {
                    case Some(slsig) =>
                      info(s"unpickling Scala $clazz and $module with long Scala signature")
                      val byteSegments = slsig map (_.getBytes)
                      val lens = byteSegments map ByteCodecs.decode
                      val bytes = Array.ofDim[Byte](lens.sum)
                      var len = 0
                      for ((bs, l) <- byteSegments zip lens) {
                        bs.copyToArray(bytes, len, l)
                        len += l
                      }
                      unpickler.unpickle(bytes, 0, clazz, module, jclazz.getName)
                    case None =>
                      // class does not have a Scala signature; it's a Java class
                      info("translating reflection info for Java " + jclazz) //debug
                      initClassAndModule(clazz, module, new FromJavaClassCompleter(clazz, module, jclazz))
                  }
      

      We get the corruption just over the boundary between the two byteSegments.

      byteSegments = {byte[2][]@5299}
      [0] = {byte[65515]@5315}
      [1] = {byte[1864]@5316}
      
      len = {scala.runtime.IntRef@5302}"58957"
      lens = {int[2]@5300}
      [0] = 57326
      [1] = 1631
      

        Activity

        Show
        Jason Zaugg added a comment - https://github.com/scala/scala/pull/2626

          People

          • Assignee:
            Jason Zaugg
            Reporter:
            Jason Zaugg
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development