diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-08-16 11:33:07 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-08-16 11:33:07 -0700 |
commit | 8b2963869f6a6416eae583d4b6f16cbcaf0ca5ac (patch) | |
tree | d6114ff58526e682331ec148d3c8a79602afbad8 /src | |
parent | 8891fdae6400478210aa122646894ecfb7223b01 (diff) | |
parent | f878bf000652c94840d6b7051011d3f9f12ef2c0 (diff) | |
download | scala-8b2963869f6a6416eae583d4b6f16cbcaf0ca5ac.tar.gz scala-8b2963869f6a6416eae583d4b6f16cbcaf0ca5ac.tar.bz2 scala-8b2963869f6a6416eae583d4b6f16cbcaf0ca5ac.zip |
Merge pull request #2803 from adriaanm/rebase-2728
SI-7658 Prevent StackOverflowError in ScalaRunTime.stringOf
Diffstat (limited to 'src')
-rw-r--r-- | src/library/scala/runtime/ScalaRunTime.scala | 34 |
1 files changed, 16 insertions, 18 deletions
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index c049de3a28..77fe2eb1e1 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -267,7 +267,18 @@ object ScalaRunTime { } def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala." def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc." - def isXmlClass(x: AnyRef) = packageOf(x) startsWith "scala.xml." + + // We use reflection because the scala.xml package might not be available + def isSubClassOf(potentialSubClass: Class[_], ofClass: String) = + try { + val classLoader = potentialSubClass.getClassLoader + val clazz = Class.forName(ofClass, /*initialize =*/ false, classLoader) + clazz.isAssignableFrom(potentialSubClass) + } catch { + case cnfe: ClassNotFoundException => false + } + def isXmlNode(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.Node") + def isXmlMetaData(potentialSubClass: Class[_]) = isSubClassOf(potentialSubClass, "scala.xml.MetaData") // When doing our own iteration is dangerous def useOwnToString(x: Any) = x match { @@ -279,11 +290,12 @@ object ScalaRunTime { case _: StringLike[_] => true // Don't want to evaluate any elements in a view case _: TraversableView[_, _] => true - // Node extends NodeSeq extends Seq[Node] and MetaData extends Iterable[MetaData] -> catch those and more by isXmlClass(x) + // Node extends NodeSeq extends Seq[Node] and MetaData extends Iterable[MetaData] + // -> catch those by isXmlNode and isXmlMetaData. // Don't want to a) traverse infinity or b) be overly helpful with peoples' custom // collections which may have useful toString methods - ticket #3710 // or c) print AbstractFiles which are somehow also Iterable[AbstractFile]s. - case x: Traversable[_] => !x.hasDefiniteSize || !isScalaClass(x) || isScalaCompilerClass(x) || isXmlClass(x) + case x: Traversable[_] => !x.hasDefiniteSize || !isScalaClass(x) || isScalaCompilerClass(x) || isXmlNode(x.getClass) || isXmlMetaData(x.getClass) // Otherwise, nothing could possibly go wrong case _ => false } @@ -324,7 +336,7 @@ object ScalaRunTime { // to be iterated, such as some scala.tools.nsc.io.AbstractFile derived classes. try inner(arg) catch { - case _: StackOverflowError | _: UnsupportedOperationException | _: AssertionError => "" + arg + case _: UnsupportedOperationException | _: AssertionError => "" + arg } } @@ -335,20 +347,6 @@ object ScalaRunTime { nl + s + "\n" } - private[scala] def checkZip(what: String, coll1: TraversableOnce[_], coll2: TraversableOnce[_]) { - if (sys.props contains "scala.debug.zip") { - val xs = coll1.toIndexedSeq - val ys = coll2.toIndexedSeq - if (xs.length != ys.length) { - Console.err.println( - "Mismatched zip in " + what + ":\n" + - " this: " + xs.mkString(", ") + "\n" + - " that: " + ys.mkString(", ") - ) - (new Exception).getStackTrace.drop(2).take(10).foreach(println) - } - } - } def box[T](clazz: jClass[T]): jClass[_] = clazz match { case java.lang.Byte.TYPE => classOf[java.lang.Byte] |