Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,19 @@ extension Google_Protobuf_ListValue: _CustomJSONCodable {
return
}
try decoder.scanner.skipRequiredArrayStart()
// Since we override the JSON decoding, we can't rely
// on the default recursion depth tracking.
// When a JSON array becomes a google.protobuf.List, that means we're
// adding an "object" to the depth of objects modeled, so manually
// include that in the recursion usage.
try decoder.scanner.incrementRecursionDepth()
defer { decoder.scanner.decrementRecursionDepth() }
if decoder.scanner.skipOptionalArrayEnd() {
decoder.scanner.decrementRecursionDepth()
return
}
while true {
var v = Google_Protobuf_Value()
try v.decodeJSON(from: &decoder)
values.append(v)
if decoder.scanner.skipOptionalArrayEnd() {
decoder.scanner.decrementRecursionDepth()
return
}
try decoder.scanner.skipRequiredComma()
Expand Down
6 changes: 6 additions & 0 deletions Sources/SwiftProtobuf/Google_Protobuf_Value+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ extension Google_Protobuf_Value: _CustomJSONCodable {
}

internal mutating func decodeJSON(from decoder: inout JSONDecoder) throws {
// No matter what was in the JSON, when it becomes a
// google.protobuf.Value, that means we've added an "object" to the
// depth of objects modeled, so manually include that in the recursion
// usage.
try decoder.scanner.incrementRecursionDepth()
defer { decoder.scanner.decrementRecursionDepth() }
let c = try decoder.scanner.peekOneCharacter()
switch c {
case "n":
Expand Down
3 changes: 2 additions & 1 deletion Tests/SwiftProtobufTests/Test_Struct.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ final class Test_JSON_ListValue: XCTestCase, PBTestHelpers {
}

func test_JSON_nested_list() throws {
let limit = JSONDecodingOptions().messageDepthLimit
// Every element in a List is a Value, so the max depth is 1/2 of the limit.
let limit = JSONDecodingOptions().messageDepthLimit / 2
let depths = [
// Small lists
1, 2, 3, 4, 5,
Expand Down