Skip to content

Commit 8ab7fd3

Browse files
committed
Fix infinite loop caused by unclosed character ref
Resolves #306 If parseCharRef is called for an unclosed character reference it will get caught in an infinite loop if the end of file is reached. Add a check to exit the loop when an EOF is encountered.
1 parent 0ccb010 commit 8ab7fd3

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

shared/src/main/scala/scala/xml/Utility.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ object Utility extends AnyRef with parsing.TokenTests {
392392
val hex: Boolean = (ch() == 'x') && { nextch(); true }
393393
val base: Int = if (hex) 16 else 10
394394
var i: Int = 0
395-
while (ch() != ';') {
395+
while (ch() != ';' && ch() != 0) {
396396
ch() match {
397397
case '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' =>
398398
i = i * base + ch().asDigit
@@ -410,6 +410,6 @@ object Utility extends AnyRef with parsing.TokenTests {
410410
}
411411
nextch()
412412
}
413-
new String(Array(i), 0, 1)
413+
if (i != 0) new String(Array(i), 0, 1) else ""
414414
}
415415
}

shared/src/test/scala/scala/xml/UtilityTest.scala

+11
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,15 @@ class UtilityTest {
219219
val x: Elem = <div>{Text(" My name ")}{Text(" is ")}{Text(" Harry ")}</div>
220220
assertEquals(<div>My name is Harry</div>, Utility.trim(x))
221221
}
222+
223+
@Test
224+
def issue306InvalidUnclosedEntity(): Unit = {
225+
val entity = "&# test </body></html>"
226+
val it: Iterator[Char] = entity.iterator
227+
var c = it.next()
228+
val next = () => if (it.hasNext) c = it.next() else c = 0.asInstanceOf[Char]
229+
val result = Utility.parseCharRef({ () => c }, next, _ => {}, _ => {})
230+
assertEquals("", result)
231+
}
232+
222233
}

0 commit comments

Comments
 (0)