From 389cdce9d4f1274c6159f591dcd2cc9dcaa2036b Mon Sep 17 00:00:00 2001 From: "Aaron S. Hawley" Date: Thu, 16 Aug 2018 09:03:41 -0400 Subject: [PATCH] Fix failure for empty string match Trying to match the empty string on descendants (or self) throws an unexpected error: scala> \\ "" java.lang.StringIndexOutOfBoundsException: String index out of range: 0 at java.lang.String.charAt(String.java:646) at scala.collection.immutable.StringOps$.apply$extension(StringOps.scala:37) at scala.xml.NodeSeq.$bslash$bslash(NodeSeq.scala:147) ... The error should be consistent with what is thrown when trying to match the empty string on just children: scala> \ "" java.lang.IllegalArgumentException at scala.xml.NodeSeq.fail$1(NodeSeq.scala:97) at scala.xml.NodeSeq.$bslash(NodeSeq.scala:120) ... This was identified while writing ScalaCheck property tests. --- shared/src/main/scala/scala/xml/NodeSeq.scala | 2 ++ shared/src/test/scala/scala/xml/XMLTest.scala | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/shared/src/main/scala/scala/xml/NodeSeq.scala b/shared/src/main/scala/scala/xml/NodeSeq.scala index fe071488f..21de379bb 100644 --- a/shared/src/main/scala/scala/xml/NodeSeq.scala +++ b/shared/src/main/scala/scala/xml/NodeSeq.scala @@ -140,8 +140,10 @@ abstract class NodeSeq extends AbstractSeq[Node] with immutable.Seq[Node] with S * The document order is preserved. */ def \\(that: String): NodeSeq = { + def fail = throw new IllegalArgumentException(that) def filt(cond: (Node) => Boolean) = this flatMap (_.descendant_or_self) filter cond that match { + case "" => fail case "_" => filt(!_.isAtom) case _ if that(0) == '@' => filt(!_.isAtom) flatMap (_ \ that) case _ => filt(x => !x.isAtom && x.label == that) diff --git a/shared/src/test/scala/scala/xml/XMLTest.scala b/shared/src/test/scala/scala/xml/XMLTest.scala index 998b06dcd..93e443119 100644 --- a/shared/src/test/scala/scala/xml/XMLTest.scala +++ b/shared/src/test/scala/scala/xml/XMLTest.scala @@ -145,6 +145,16 @@ class XMLTest { assertEquals(expected, actual) } + @UnitTest(expected=classOf[IllegalArgumentException]) + def failEmptyStringChildren: Unit = { + \ "" + } + + @UnitTest(expected=classOf[IllegalArgumentException]) + def failEmptyStringDescendants: Unit = { + \\ "" + } + @UnitTest def namespaces: Unit = { val cuckoo =