Skip to content

Commit ee5b6fc

Browse files
committed
Fix handling of failing entity expansion in attribute values. Add tests
that ensure entity expansion works in both expansion and non-expansion modes by always expanding entities in attribute values.
1 parent 1f52805 commit ee5b6fc

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

core/base/src/commonMain/kotlin/nl/adaptivity/xmlutil/core/KtXmlReader.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -921,18 +921,18 @@ public class KtXmlReader internal constructor(
921921
* result: if the setName parameter is set,
922922
* the name of the entity is stored in "name"
923923
*/
924-
private fun pushEntity() {
924+
private fun pushEntity(expandEntities: Boolean = this.expandEntities) {
925925
readAssert('&')
926926
val first = peek(0)
927927

928928
when {
929929
first == '#'.code -> pushCharEntity()
930930
first < 0 -> error(UNEXPECTED_EOF)
931-
else -> pushRefEntity()
931+
else -> pushRefEntity(expandEntities)
932932
}
933933
}
934934

935-
private fun pushRefEntity() {
935+
private fun pushRefEntity(expandEntities: Boolean) {
936936
unresolvedEntity = false
937937
val first = read()
938938
val codeBuilder = StringBuilder(8)
@@ -1265,7 +1265,7 @@ public class KtXmlReader internal constructor(
12651265
'&' -> when {
12661266
left == curPos -> { // start with entity
12671267
srcBufPos = curPos
1268-
pushEntity()
1268+
pushEntity(expandEntities = true) // always expand attribute values
12691269
curPos = srcBufPos
12701270
left = curPos
12711271
}

core/base/src/commonTest/kotlin/nl/adaptivity/xmlutil/test/TestKtXmlReaderExpandEntities.kt

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024-2025.
2+
* Copyright (c) 2024-2026.
33
*
44
* This file is part of xmlutil.
55
*
@@ -35,9 +35,18 @@ class TestKtXmlReaderExpandEntities : TestCommonReader() {
3535
}
3636

3737
@Test
38-
fun testReadEntityInAttribute() {
38+
fun testReadEntityInAttributeExpand() {
39+
testReadEntityInAttribute(true)
40+
}
41+
42+
@Test
43+
fun testReadEntityInAttributeNoExpand() {
44+
testReadEntityInAttribute(false)
45+
}
46+
47+
private fun testReadEntityInAttribute(expandEntities: Boolean) {
3948
val data = "<tag attr=\"&lt;xx&gt;\"/>"
40-
val reader = KtXmlReader(StringReader(data))
49+
val reader = KtXmlReader(StringReader(data), expandEntities)
4150
var e = reader.next()
4251
if (e == EventType.START_DOCUMENT) e = reader.next()
4352
assertEquals(EventType.START_ELEMENT, e)
@@ -76,6 +85,28 @@ class TestKtXmlReaderExpandEntities : TestCommonReader() {
7685
assertEquals( "Unknown entity \"&unknown;\" in entity expanding mode", e.message!!.substringAfter(" - "))
7786
}
7887

88+
@Test
89+
fun testReadUnknownEntityInAttributeNoExpand() {
90+
testReadUnknownEntityInAttribute(false)
91+
}
92+
93+
@Test
94+
fun testReadUnknownEntityInAttributeExpand() {
95+
testReadUnknownEntityInAttribute(true)
96+
}
97+
98+
private fun testReadUnknownEntityInAttribute(expandEntities: Boolean) {
99+
val xml = """<tag attr="&unknown;"/>"""
100+
val e = assertFailsWith<XmlException> {
101+
KtXmlReader(StringReader(xml), expandEntities).use { reader ->
102+
assertEquals(EventType.START_ELEMENT, reader.nextTag())
103+
assertNotEquals("&unknown;", reader.getAttributeValue(0))
104+
assertNotEquals("", reader.getAttributeValue(0))
105+
}
106+
}
107+
assertEquals("Unknown entity \"&unknown;\" in entity expanding mode", e.message!!.substringAfter(" - "))
108+
}
109+
79110
@Test
80111
override fun testWhiteSpaceWithEntity() {
81112
val data = "<x> dude &amp; &lt;dudette&gt; </x>"

0 commit comments

Comments
 (0)