Skip to content

swiftlint crashes due to duplicate keys in configuration #6052

@dimlio

Description

@dimlio

New Issue Checklist

Bug Description

Swiftlint crashes while trying to read .swiftlint.yml with duplicating keys in sub-directory.

$ find .
.
./subdir
./subdir/.swiftlint.yml
./subdir/a.swift
$ cat subdir/.swiftlint.yml 
opt_in_rules:
  - closure_body_length

opt_in_rules:
  - closure_body_length
$ ~/GitHub/SwiftLint/.build/debug/swiftlint
Linting Swift files in current working directory
The operation couldn’t be completed. (SwiftLintCore.Issue error 15.)
Could not read configuration: file Configuration.swift, line 289
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Abort trap: 6 (core dumped)
$ ~/GitHub/SwiftLint/.build/debug/swiftlint --version
0.59.0

If I run swiftlint in subdirectory it correctly reports an error:

$ cd subdir/
$ ~/GitHub/SwiftLint/.build/debug/swiftlint 
warning: Cannot parse YAML file: error: parser: expected all keys to be unique but found the following duplicated key(s):
opt_in_rules ([1:1, 4:1]):
opt_in_rules:
^
opt_in_rules:
^ – Falling back to default configuration
Linting Swift files in current working directory
Linting 'a.swift' (1/1)
Done linting! Found 0 violations, 0 serious in 1 file.

Stacktrace:

thread #2
    frame #0: 0x000000018e4f0388 libsystem_kernel.dylib`__pthread_kill + 8
    frame #1: 0x000000018e52988c libsystem_pthread.dylib`pthread_kill + 296
    frame #2: 0x000000018e432cf0 libsystem_c.dylib`__abort + 132
    frame #3: 0x000000018e432c6c libsystem_c.dylib`abort + 136
    frame #4: 0x000000010312be78 swiftlint`queuedFatalError(string="Could not read configuration", file="SwiftLintFramework/Configuration.swift", line=289) at QueuedPrint.swift:61:5
    frame #5: 0x00000001031ba218 swiftlint`Configuration.init(configurationFiles=1 value, enableAllRules=false, onlyRule=0 values, cachePath=nil, ignoreParentAndChildConfigs=true, mockedNetworkResults=0 key/value pairs, useDefaultConfigOnFailure=nil) at Configuration.swift:289:17
    frame #6: 0x00000001031a1148 swiftlint`Configuration.configuration(directory=Swift.String @ 0x000000016d5ec730) at Configuration+Merging.swift:117:38
    frame #7: 0x00000001031a0c70 swiftlint`implicit closure #2 in implicit closure #1 in Configuration.configuration() at Configuration+Merging.swift:88:61
    frame #8: 0x00000001031a177c swiftlint`thunk for @callee_guaranteed (@guaranteed String) -> (@owned Configuration) at <compiler-generated>:0
    frame #9: 0x00000001031a17c4 swiftlint`partial apply for thunk for @callee_guaranteed (@guaranteed String) -> (@owned Configuration) at <compiler-generated>:0
    frame #10: 0x00000001028c1704 swiftlint`Optional.map<String, B>(_:) at <compiler-generated>:0
    frame #11: 0x00000001031a0a94 swiftlint`Configuration.configuration(file=0x00006000019a41e0) at Configuration+Merging.swift:88:57
    frame #12: 0x000000010318c788 swiftlint`closure #1 in Configuration.groupFiles(file=0x00006000019a41e0) at Configuration+CommandLine.swift:115:37
    frame #13: 0x00000001030f2e64 swiftlint`Array.filterGroup<SwiftLintCore.SwiftLintFile>(transform=0x1031902bc) at Array+SwiftLint.swift:76:26
    frame #14: 0x00000001030f3698 swiftlint`Array.parallelFilterGroup<SwiftLintCore.SwiftLintFile>(transform=0x1031902bc) at Array+SwiftLint.swift:93:20
    frame #15: 0x0000000103188f20 swiftlint`Configuration.groupFiles(files=1 value, visitor=SwiftLintFramework.LintableFilesVisitor @ 0x0000000116827840) at Configuration+CommandLine.swift:114:22
    frame #16: 0x0000000103188b28 swiftlint`closure #2 in Configuration.visitLintableFiles(, files=1 value, visitor=SwiftLintFramework.LintableFilesVisitor @ 0x0000000116827840) at Configuration+CommandLine.swift:82:17
    frame #17: 0x0000000103188b98 swiftlint`partial apply for closure #2 in Configuration.visitLintableFiles(with:storage:) at <compiler-generated>:0
    frame #18: 0x00000001031fc5dc swiftlint`static Signposts.record<[SwiftLintFramework.Configuration : [SwiftLintCore.SwiftLintFile]]>(name="Configuration.VisitLintableFiles.GroupFiles", span=timeline, body=0x103188b78) at Signposts.swift:32:26
    frame #19: 0x0000000103186848 swiftlint`Configuration.visitLintableFiles(visitor=SwiftLintFramework.LintableFilesVisitor @ 0x0000000116833348, storage=0x00006000017bd740) at Configuration+CommandLine.swift:81:42
    frame #20: 0x0000000103190854 swiftlint`Configuration.visitLintableFiles(options=SwiftLintFramework.LintOrAnalyzeOptions @ 0x000000011681f840, cache=0x00006000039bc680, storage=0x00006000017bd740, visitorBlock=0x0000000104003b88 async function pointer to partial apply forwarder for closure #1 (SwiftLintFramework.CollectedLinter) async -> () in static SwiftLintFramework.LintOrAnalyzeCommand.collectViolations(builder: SwiftLintFramework.LintOrAnalyzeResultBuilder) async throws -> Swift.Array<SwiftLintCore.SwiftLintFile>) at Configuration+CommandLine.swift:293:26
    frame #21: 0x00000001031cd6a4 swiftlint`static LintOrAnalyzeCommand.collectViolations(builder=0x00000001371060a0) at LintOrAnalyzeCommand.swift:163:48
    frame #22: 0x00000001031cca3c swiftlint`static LintOrAnalyzeCommand.lintOrAnalyze(options=SwiftLintFramework.LintOrAnalyzeOptions @ 0x0000000137810620) at LintOrAnalyzeCommand.swift:144:31
    frame #23: 0x00000001031cbb70 swiftlint`closure #1 in static LintOrAnalyzeCommand.run(options=SwiftLintFramework.LintOrAnalyzeOptions @ 0x0000000137810620) at LintOrAnalyzeCommand.swift:138:68
    frame #24: 0x00000001031cbc78 swiftlint`partial apply for closure #1 in static LintOrAnalyzeCommand.run(_:) at <compiler-generated>:0
    frame #25: 0x00000001031fcea0 swiftlint`static Signposts.record<()>(name="LintOrAnalyzeCommand.run", span=timeline, body=0x104003b40) at Signposts.swift:63:32
    frame #26: 0x00000001031cb868 swiftlint`static LintOrAnalyzeCommand.run(options=SwiftLintFramework.LintOrAnalyzeOptions @ 0x0000000137810918) at LintOrAnalyzeCommand.swift:137:29
    frame #27: 0x0000000103c22afc swiftlint`SwiftLint.Lint.run() at Lint.swift:63:44
    frame #28: 0x0000000103c257f8 swiftlint`protocol witness for AsyncParsableCommand.run() in conformance SwiftLint.Lint at <compiler-generated>:0
    frame #29: 0x00000001028cb8cc swiftlint`static AsyncParsableCommand.main(arguments=nil) at AsyncParsableCommand.swift:41:32
    frame #30: 0x00000001028cbbf0 swiftlint`static AsyncParsableCommand.main() at AsyncParsableCommand.swift:61:16
    frame #31: 0x0000000103c412bc swiftlint`static SwiftLint.$main() at SwiftLint.swift:9:1
    frame #32: 0x0000000103c4182c swiftlint`async_MainTQ0_ at SwiftLint.swift:10:8
    frame #33: 0x0000000103c41950 swiftlint`thunk for @escaping @convention(thin) @async () -> () at <compiler-generated>:0
    frame #34: 0x0000000103c41a78 swiftlint`partial apply for thunk for @escaping @convention(thin) @async () -> () at <compiler-generated>:0

At least 0.57.0 doesn't crash, so looks like recent regression.
I tried to bisect but stuck due to:

$ git bisect good
Bisecting: 135 revisions left to test after this (roughly 7 steps)
[7421e24fc281d73d4c37550f95054751b4fc0f8f] Use action to extract binary from Docker image
$ swift build
Fetching https://github.com/ileitch/swift-filename-matcher
Updating https://github.com/jpsim/SourceKitten.git
Updating https://github.com/drmohundro/SWXMLHash.git
...
Downloading binary artifact https://github.com/realm/SwiftLint/releases/download/0.57.1/SwiftLintBinary.artifactbundle.zip
error: failed downloading 'https://github.com/realm/SwiftLint/releases/download/0.57.1/SwiftLintBinary.artifactbundle.zip' which is required by binary target 'SwiftLintBinary': badResponseStatusCode(404)

Environment

  • SwiftLint version (run swiftlint version to be sure)
    0.59.0

  • Installation method used (Homebrew, CocoaPods, building from source, etc)
    Built from source.

  • Configuration file:

opt_in_rules:
  - closure_body_length

opt_in_rules:
  - closure_body_length

Metadata

Metadata

Assignees

Labels

bugUnexpected and reproducible misbehavior.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions