diff options
author | Simon Ochsenreither <simon@ochsenreither.de> | 2013-07-13 13:58:31 +0200 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-08-08 11:59:54 -0700 |
commit | fbad9938cca229f61686f01dc8afa792a19f86df (patch) | |
tree | bf2929737259a0756842cfce8be46e22f97d2359 /src/library | |
parent | e7876d5c41bbea0ee4679815edb5dc1ecef4c6a9 (diff) | |
download | scala-fbad9938cca229f61686f01dc8afa792a19f86df.tar.gz scala-fbad9938cca229f61686f01dc8afa792a19f86df.tar.bz2 scala-fbad9938cca229f61686f01dc8afa792a19f86df.zip |
SI-7658 Prevent StackOverflowError in ScalaRunTime.stringOf
Diffstat (limited to 'src/library')
-rw-r--r-- | src/library/scala/runtime/ScalaRunTime.scala | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index c049de3a28..583a1c790f 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 } } |