Skip to content

Commit

Permalink
fix(#16458): regression in xml syntax parsing
Browse files Browse the repository at this point in the history
xLiteral mistakenly assumed that the element just after `<` is always
non-special element, but it is not true. It could be xCharData, comment,
xProcInstr.

[Cherry-picked 77aa363]
  • Loading branch information
i10416 authored and WojciechMazur committed Jul 2, 2024
1 parent 42272ff commit 4be0636
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,14 @@ private[dotty] trait MarkupParserCommon {
/** skip optional space S? */
def xSpaceOpt(): Unit = while (isSpace(ch) && !eof) nextch()

/** skip optional space S? and return the number of consumed characters */
def xSpaceOptN(): Int =
var i = 0
while (isSpace(ch) && !eof) do
nextch()
i += 1
i

/** scan [3] S ::= (#x20 | #x9 | #xD | #xA)+ */
def xSpace(): Unit =
if (isSpace(ch)) { nextch(); xSpaceOpt() }
Expand Down
15 changes: 11 additions & 4 deletions compiler/src/dotty/tools/dotc/parsing/xml/MarkupParsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -370,10 +370,17 @@ object MarkupParsers {
// parse more XML?
if (charComingAfter(xSpaceOpt()) == '<') {
while {
xSpaceOpt()
nextch()
ts.append(element)
charComingAfter(xSpaceOpt()) == '<'
if xSpaceOptN() == 0 then
nextch()
if content_LT(ts) then // Is `</>` valid xml?
xToken("/>")
charComingAfter(xSpaceOpt()) == '<'
else
// this is surely not a special node as any special node
// should start with `<{special symbol}` without space.
nextch()
ts.append(element)
charComingAfter(xSpaceOpt()) == '<'
} do ()
handle.makeXMLseq(Span(start, curOffset, start), ts)
}
Expand Down
37 changes: 37 additions & 0 deletions tests/pos/i16458.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
def x = <div>FooBar</div><!-- /.modal-content -->

package scala.xml {
type MetaData = AnyRef

trait NamespaceBinding
object TopScope extends NamespaceBinding
object Null
abstract class Node {
def label: String
def child: Seq[Node]
override def toString = label + child.mkString
}
class Comment(commentText: String) extends Node{
def label = commentText
def child = Nil
}
class Elem(prefix: String, val label: String, attributes1: MetaData, scope: NamespaceBinding, minimizeEmpty: Boolean, val child: Node*) extends Node
class NodeBuffer extends Seq[Node] {
val nodes = scala.collection.mutable.ArrayBuffer.empty[Node]
def &+(o: Any): NodeBuffer =
o match {
case n: Node => nodes.addOne(n) ; this
case t: Text => nodes.addOne(Atom(t)) ; this
}
// Members declared in scala.collection.IterableOnce
def iterator: Iterator[scala.xml.Node] = nodes.iterator
// Members declared in scala.collection.SeqOps
def apply(i: Int): scala.xml.Node = nodes(i)
def length: Int = nodes.length
}
case class Text(text: String)
case class Atom(t: Text) extends Node {
def label = t.text
def child = Nil
}
}

0 comments on commit 4be0636

Please sign in to comment.