Skip to content

JSONEncoder can't encode what JSONDecoder decoded (they disagree on limits...) #1176

Open
@weissi

Description

@weissi

Consider JSONs like

{
  "nestedArray": [
    {
      "nestedArray": [
        {
          "nestedArray": [
            {
              "nestedArray": [
                {
                  "nestedArray": [
                    {
                      "nestedArray": []
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

but deeper (for example bug1.json which has 255 levels). Now consider this program which decodes a thing and then reencodes it:

import Foundation

struct Thing: Codable {
    var nestedArray: [Thing]?
}

do {
    let data = try Data(contentsOf: URL(fileURLWithPath: CommandLine.arguments.dropFirst().first ?? "/tmp/file.json"))
    let decoded = try JSONDecoder().decode(Thing.self, from: data)
    do {
        let encoded = try JSONEncoder().encode(decoded)
        print("OK", encoded)
    } catch {
        print("encode ERROR", error)
    }
} catch {
    print("decode (or earlier) ERROR:", error)
}

You'd expect that JSONEncoder can encode everything that JSONDecoder decoded. But alas, here's what we see:

$ swiftc -O test.swift && ./test bug1.json
encode ERROR invalidValue(test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([test.Thing(nestedArray: Optional([]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))]))])), Swift.EncodingError.Context(codingPath: [], debugDescription: "Unable to encode the given top-level value to JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Too many nested arrays or dictionaries." UserInfo={NSDebugDescription=Too many nested arrays or dictionaries.})))

bug1.json

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions