summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2013-08-16 11:33:07 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-08-16 11:33:07 -0700
commit8b2963869f6a6416eae583d4b6f16cbcaf0ca5ac (patch)
treed6114ff58526e682331ec148d3c8a79602afbad8
parent8891fdae6400478210aa122646894ecfb7223b01 (diff)
parentf878bf000652c94840d6b7051011d3f9f12ef2c0 (diff)
downloadscala-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
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala34
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]