@@ -25,6 +25,7 @@ internal open class StreamingJsonDecoder(
2525 descriptor : SerialDescriptor ,
2626 discriminatorHolder : DiscriminatorHolder ?
2727) : JsonDecoder, ChunkedDecoder, AbstractDecoder() {
28+ private val coercePrimitives = json.configuration.allowPrimitiveCoercion
2829
2930 // A mutable reference to the discriminator that have to be skipped when in optimistic phase
3031 // of polymorphic serialization, see `decodeSerializableValue`
@@ -273,47 +274,51 @@ internal open class StreamingJsonDecoder(
273274 }
274275
275276 /*
276- * The primitives are allowed to be quoted and unquoted
277- * to simplify map key parsing and integrations with third-party API.
278- */
277+ * The primitives are allowed to be quoted and unquoted
278+ * to simplify map key parsing and integrations with third-party API.
279+ */
279280 override fun decodeBoolean (): Boolean {
280- return lexer.consumeBooleanLenient()
281+ return if (coercePrimitives) {
282+ lexer.consumeBooleanLenient()
283+ } else {
284+ lexer.consumeBoolean()
285+ }
281286 }
282287
283288 override fun decodeByte (): Byte {
284- val value = lexer.consumeNumericLiteral()
289+ val value = lexer.consumeNumericLiteral(coercePrimitives )
285290 // Check for overflow
286291 if (value != value.toByte().toLong()) lexer.fail(" Failed to parse byte for input '$value '" )
287292 return value.toByte()
288293 }
289294
290295 override fun decodeShort (): Short {
291- val value = lexer.consumeNumericLiteral()
296+ val value = lexer.consumeNumericLiteral(coercePrimitives )
292297 // Check for overflow
293298 if (value != value.toShort().toLong()) lexer.fail(" Failed to parse short for input '$value '" )
294299 return value.toShort()
295300 }
296301
297302 override fun decodeInt (): Int {
298- val value = lexer.consumeNumericLiteral()
303+ val value = lexer.consumeNumericLiteral(coercePrimitives )
299304 // Check for overflow
300305 if (value != value.toInt().toLong()) lexer.fail(" Failed to parse int for input '$value '" )
301306 return value.toInt()
302307 }
303308
304309 override fun decodeLong (): Long {
305- return lexer.consumeNumericLiteral()
310+ return lexer.consumeNumericLiteral(coercePrimitives )
306311 }
307312
308313 override fun decodeFloat (): Float {
309- val result = lexer.parseString(" float" ) { toFloat() }
314+ val result = lexer.parseString(" float" , coercePrimitives ) { toFloat() }
310315 val specialFp = json.configuration.allowSpecialFloatingPointValues
311316 if (specialFp || result.isFinite()) return result
312317 lexer.throwInvalidFloatingPointDecoded(result)
313318 }
314319
315320 override fun decodeDouble (): Double {
316- val result = lexer.parseString(" double" ) { toDouble() }
321+ val result = lexer.parseString(" double" , coercePrimitives ) { toDouble() }
317322 val specialFp = json.configuration.allowSpecialFloatingPointValues
318323 if (specialFp || result.isFinite()) return result
319324 lexer.throwInvalidFloatingPointDecoded(result)
@@ -374,15 +379,16 @@ internal class JsonDecoderForUnsignedTypes(
374379) : AbstractDecoder() {
375380 override val serializersModule: SerializersModule = json.serializersModule
376381 override fun decodeElementIndex (descriptor : SerialDescriptor ): Int = error(" unsupported" )
382+ private val coercePrimitves = json.configuration.allowPrimitiveCoercion
377383
378- override fun decodeInt (): Int = lexer.parseString(" UInt" ) { toUInt().toInt() }
379- override fun decodeLong (): Long = lexer.parseString(" ULong" ) { toULong().toLong() }
380- override fun decodeByte (): Byte = lexer.parseString(" UByte" ) { toUByte().toByte() }
381- override fun decodeShort (): Short = lexer.parseString(" UShort" ) { toUShort().toShort() }
384+ override fun decodeInt (): Int = lexer.parseString(" UInt" , coercePrimitves ) { toUInt().toInt() }
385+ override fun decodeLong (): Long = lexer.parseString(" ULong" , coercePrimitves ) { toULong().toLong() }
386+ override fun decodeByte (): Byte = lexer.parseString(" UByte" , coercePrimitves ) { toUByte().toByte() }
387+ override fun decodeShort (): Short = lexer.parseString(" UShort" , coercePrimitves ) { toUShort().toShort() }
382388}
383389
384- private inline fun <T > AbstractJsonLexer.parseString (expectedType : String , block : String .() -> T ): T {
385- val input = consumeStringLenient( )
390+ private inline fun <T > AbstractJsonLexer.parseString (expectedType : String , coercePrimitives : Boolean , block : String .() -> T ): T {
391+ val input = consumeOther(allowQuoted = coercePrimitives )
386392 try {
387393 return input.block()
388394 } catch (e: IllegalArgumentException ) {
0 commit comments