swiftlang / swiftlang/swift-corelibs-libdispatch

[SR-1941] Dispatch object creation can return nil despite non-nil type annotations

Open
#738 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug libdispatch
Dominant language
C
Stars
2.6k
Forks
496
Avg merge
2d 6h
Merged PRs (30d)
3

Description

Previous ID SR-1941
Radar None
Original Reporter miken (JIRA User)
Type Bug
Additional Detail from JIRA
Votes 0
Component/s libdispatch
Labels Bug
Assignee mww (JIRA)
Priority Medium

md5: d1490ba04e755f83c340b8874532c6bf

Issue Description:

Attempting to create a dispatch source or I/O channel is a fallible operation. In Swift 2.2 the functions used for creating them are annotated as returning implicitly-unwrapped optionals, and nil is returned when creation fails. This can be checked for and handled appropriately.

In Swift 2.3 and 3.0 the functions/initializers are annotated as returning non-nil values, but nil can still be returned. This can be reproduced by providing invalid parameters.

The code below will run successfully under Swift 2.2, but will crash at runtime under 2.3 and 3.0 despite the lack of any forced or implicit unwrapping.

#if swift(>=3.0)
    
    let channel = DispatchIO(type: .stream, path: "../bad.path", oflag: O_RDONLY, mode: S_IRUSR, queue: .main) { (error) in
        print(error)
    }
    print(channel) // Crash
    
    let source = DispatchSource.signal(signal: Int32.min)
    print(source) // Crash
    
#elseif swift(>=2.3)
    
    let channel = dispatch_io_create_with_path(DISPATCH_IO_STREAM, "../bad.path", O_RDONLY, S_IRUSR, dispatch_get_main_queue()) { (error) in
        print(error)
    }
    print(channel) // Crash
    
    let source = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, UInt.max, 0, dispatch_get_main_queue())
    print(source) // Crash
    
#else
    
    let channel = dispatch_io_create_with_path(DISPATCH_IO_STREAM, "../bad.path", O_RDONLY, S_IRUSR, dispatch_get_main_queue()) { (error) in
        print(error)
    }
    print(channel ?? "Nil") // Nil
    
    let source = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, UInt.max, 0, dispatch_get_main_queue())
    print(source ?? "Nil") // Nil
    
#endif

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the failure with the DispatchIO initializer and DispatchSource.signal, or the C entry points dispatch_io_create_with_path and dispatch_source_create, using the invalid parameters shown. Compare the Swift 2.2 nil behavior with Swift 2.3 and 3.0, then trace how the non-nil annotations are exposed; done should mean invalid creation cannot crash callers that handle the result as described.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, swift
Domain
operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.