Skip to content

Commit

Permalink
Handle empty tags with value child of list types correctly.
Browse files Browse the repository at this point in the history
  • Loading branch information
pdvrieze committed Feb 10, 2024
1 parent 920153a commit 75967a3
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 3 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Fixes:
- Fix handling of empty `@XmlValue` members of string-like type. Also
collapse whitespace when parsing non-string primitives (per xml
schema). Strings never ignore whitespace.
- Fix handling `XmlValue` members of collection type inside an empty tag.
- Fix parsing of `XmlDefault` attributes if the (effective) type is an
attribute and it is parsed using as serializable value (rather than)
directly as primitive.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1014,9 +1014,13 @@ internal open class XmlDecoderBase internal constructor(
// Handle the case of an empty tag for a value child. This is not a nullable item (so shouldn't be
// treated as such).
if (valueChild >= 0 && input.peek() is XmlEvent.EndElementEvent && !seenItems[valueChild]) {
// This code can rely on seenItems to avoid infinite item loops as it only triggers on an empty tag.
seenItems[valueChild] = true
return valueChild
val valueChildDesc = xmlDescriptor.getElementDescriptor(valueChild)
// Lists/maps need to be empty (treated as null/missing)
if (valueChildDesc.kind !is StructureKind.LIST && valueChildDesc.kind !is StructureKind.MAP) {
// This code can rely on seenItems to avoid infinite item loops as it only triggers on an empty tag.
seenItems[valueChild] = true
return valueChild
}
}
for (eventType in input) {
when (eventType) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2024.
*
* This file is part of xmlutil.
*
* This file is licenced to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You should have received a copy of the license with the source distribution.
* Alternatively, you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package nl.adaptivity.xml.serialization.regressions

import io.github.pdvrieze.xmlutil.testutil.assertXmlEquals
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import nl.adaptivity.xmlutil.serialization.XML
import nl.adaptivity.xmlutil.serialization.XmlValue
import nl.adaptivity.xmlutil.util.CompactFragment
import kotlin.test.Test
import kotlin.test.assertEquals

class EmptyTagWithValueChild {

@Test
fun testSerializeStr() {
val actual = XML.encodeToString(OuterStr(InnerStr("")))
assertXmlEquals("<Outer><Inner /></Outer>", actual)
}


@Test
fun testSerializeCF() {
val actual = XML.encodeToString(OuterFrag(InnerFrag(emptyList())))
assertXmlEquals("<Outer><Inner /></Outer>", actual)
}

@Test
fun testDeserializeCF() {
val expected = OuterFrag(InnerFrag(emptyList()))
val actual = XML.decodeFromString<OuterFrag>("<Outer><Inner /></Outer>")
assertEquals(expected, actual)
}

@Test
fun testDeserializeStr() {
val expected = OuterStr(InnerStr(""))
val actual = XML.decodeFromString<OuterStr>("<Outer><Inner /></Outer>")
assertEquals(expected, actual)
}


@Serializable
@SerialName("Outer")
private data class OuterStr(val inner: InnerStr)

@Serializable
@SerialName("Inner")
private data class InnerStr(@XmlValue val value: String)

@Serializable
@SerialName("Outer")
private data class OuterFrag(val inner: InnerFrag)

@Serializable
@SerialName("Inner")
private data class InnerFrag(@XmlValue val values: List<CompactFragment>)
}

0 comments on commit 75967a3

Please sign in to comment.