From b21797682ea59d9c35eec77b4b03f74feb8aea06 Mon Sep 17 00:00:00 2001 From: Daniel Duan Date: Fri, 10 Jul 2026 10:39:01 -0700 Subject: [PATCH] Reject top-level single-value decoding --- Sources/TOMLDecoder/_TOMLDecoder.swift | 11 ++++++++++- Tests/TOMLDecoderTests/TOMLDecoderTests.swift | 6 ++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Sources/TOMLDecoder/_TOMLDecoder.swift b/Sources/TOMLDecoder/_TOMLDecoder.swift index d46600d8..43b37220 100644 --- a/Sources/TOMLDecoder/_TOMLDecoder.swift +++ b/Sources/TOMLDecoder/_TOMLDecoder.swift @@ -51,7 +51,16 @@ final class _TOMLDecoder: Decoder { } func singleValueContainer() throws -> any SingleValueDecodingContainer { - self + guard token != .empty else { + throw DecodingError.typeMismatch( + (any SingleValueDecodingContainer).self, + DecodingError.Context( + codingPath: codingPath, + debugDescription: "Cannot decode a single value from a TOML table." + ) + ) + } + return self } init(referencing container: Container, at codingPath: [any CodingKey] = [], strategy: TOMLDecoder.Strategy, isLenient: Bool) { diff --git a/Tests/TOMLDecoderTests/TOMLDecoderTests.swift b/Tests/TOMLDecoderTests/TOMLDecoderTests.swift index 329d80e1..96f83ba8 100644 --- a/Tests/TOMLDecoderTests/TOMLDecoderTests.swift +++ b/Tests/TOMLDecoderTests/TOMLDecoderTests.swift @@ -501,6 +501,12 @@ struct TOMLDecoderTests { #expect(result == Team(languages: [.swift, .mojo, .zig], favorite: .swift)) } + @Test func topLevelTableCannotDecodeAsSingleValue() { + #expect(throws: DecodingError.self) { + try TOMLDecoder().decode(Int.self, from: "-1 = true") + } + } + @Test func twitter() throws { _ = try TOMLDecoder().decode(TwitterArchive.self, from: Resources.twitterTOMLString) }