Skip to content

Commit

Permalink
Fix nullable QName parsing in a way that doesn't stop inline
Browse files Browse the repository at this point in the history
structs from working. Do this by detecting the use of
nullableSerializable parsing (decodeNotNullMark). Otherwise there is
recursion.
  • Loading branch information
pdvrieze committed Aug 9, 2023
1 parent 8151b57 commit 430d303
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 8 deletions.
2 changes: 2 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Fixes:
- For attribute lists, make sure to collapse the whitespace.
- When attributes have an `@XmlSerialName` annotation with a default namespace
value, then this will result in a non-qualified attribute.
- Fix nullable QName serialization (and probably other nullable inline-like)
serialization.

# 0.86.1
*(July 5, 2023)<br />*
Expand Down
10 changes: 5 additions & 5 deletions core/src/commonMain/kotlin/nl/adaptivity/xmlutil/XmlReader.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018.
* Copyright (c) 2023.
*
* This file is part of XmlUtil.
* 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
Expand Down Expand Up @@ -67,15 +67,15 @@ public interface XmlReader : Closeable, Iterator<EventType> {
public fun require(type: EventType, namespace: String?, name: String?) {
when {
eventType != type ->
throw XmlException("Type $eventType does not match expected type \"$type\"")
throw XmlException("Type $eventType does not match expected type \"$type\" ($locationInfo)")

namespace != null &&
namespaceURI != namespace ->
throw XmlException("Namespace $namespaceURI does not match expected \"$namespace\"")
throw XmlException("Namespace $namespaceURI does not match expected \"$namespace\" ($locationInfo)")

name != null &&
localName != name ->
throw XmlException("local name $localName does not match expected \"$name\"")
throw XmlException("local name $localName does not match expected \"$name\" ($locationInfo)")
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018.
* Copyright (c) 2023.
*
* This file is part of XmlUtil.
* 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
Expand Down Expand Up @@ -300,6 +300,7 @@ internal open class XmlDecoderBase internal constructor(
attrIndex: Int/* = -1*/,
override val typeDiscriminatorName: QName?
) : XmlDecoder(xmlDescriptor, polyInfo, attrIndex) {
private var notNullChecked = false

public var tagIdHolder: TagIdHolder? = null

Expand All @@ -317,6 +318,19 @@ internal open class XmlDecoderBase internal constructor(
return value
}

override fun decodeNotNullMark(): Boolean {
notNullChecked = true
return super.decodeNotNullMark()
}

override fun <T> decodeSerializableValue(deserializer: DeserializationStrategy<T>): T {
return when {
notNullChecked -> deserializer.deserialize(this)
else -> super.decodeSerializableValue(deserializer)
}
//return deserializer.deserialize(this) // Revert to default
}

@ExperimentalSerializationApi
override fun decodeInline(descriptor: SerialDescriptor): Decoder {
tagIdHolder = object: TagIdHolder {
Expand Down Expand Up @@ -584,6 +598,8 @@ internal open class XmlDecoderBase internal constructor(
if (((effectiveDeserializer as DeserializationStrategy<*>) == CompactFragmentSerializer) &&
(xmlDescriptor.getValueChild() == index)
) {
// handle missing compact fragments
if (nulledItemsIdx>=0) return (CompactFragment("") as T)
// input.require(EventType.START_ELEMENT, null)
return input.siblingsToFragment().let {
input.pushBackCurrent() // Make the closing tag again be the next read.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package nl.adaptivity.xmlutil.serialization
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerializationException
import kotlinx.serialization.builtins.nullable
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.modules.SerializersModule
import nl.adaptivity.xmlutil.*
Expand Down Expand Up @@ -601,7 +602,10 @@ private constructor(
): KSerializer<*>? =
when (serializerParent.elementSerialDescriptor.serialName) {
"javax.xml.namespace.QName?",
"javax.xml.namespace.QName" -> XmlQNameSerializer
"javax.xml.namespace.QName" -> when {
serializerParent.elementSerialDescriptor.isNullable -> XmlQNameSerializer.nullable
else -> XmlQNameSerializer
}

else -> null
}
Expand Down

0 comments on commit 430d303

Please sign in to comment.