Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bugs in async code #753

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Commits on Jul 26, 2023

  1. Fix bugs in async code

    1. Insert `-` in `echo -nE "$suggestion"`. This is necessary to prevent
       `"$suggestion"` from being treated as an option for `echo`.
    2. Close file descriptors only in `_zsh_autosuggest_async_response` to
       ensure that each file descriptor is closed only once.
    
    It's the second bug that prompted the fix. The original code in some
    cases could close the same file descriptor twice. The code relied on
    an invalid assumption that `_zsh_autosuggest_async_response` cannot
    fire after the file descriptor is closed. Here's a demo that shows
    this assumption being violated:
    
        () {
          emulate -L zsh
    
          function callback1() {
            zle -I
            emulate -L zsh -o xtrace
            : "$@"
            zle -F $fd1
            exec {fd1}>&-
            zle -F $fd2
            exec {fd2}>&-
          }
    
          function callback2() {
            zle -I
            emulate -L zsh -o xtrace
            : "$@"
          }
    
          exec {fd1} </dev/null
          exec {fd2} </dev/null
          zle -F $fd1 callback1
          zle -F $fd2 callback2
        }
    
    And here's the output I get if the code is pasted into an interactive zsh:
    
        +callback1:3> : 12
        +callback1:4> zle -F 12
        +callback1:6> zle -F 13
        +callback2:3> : 13
    
    Note that `callback2` fires after its file descriptor has been closed
    by `callback1`.
    
    This bug was the culprit of several issues filed against powerlevel10k.
    In a nutshell:
    
    1. `_zsh_autosuggest_async_request` opens a file.
    2. `_zsh_autosuggest_async_request` closes the file descriptor.
    3. powerlevel10k opens a file and gets the same file descriptor as above.
    4. `_zsh_autosuggest_async_response` fires and closes the same file descriptor.
    5. powerlevel10k encounters errors when trying to read from the file descriptor.
    romkatv committed Jul 26, 2023
    Configuration menu
    Copy the full SHA
    167d52e View commit details
    Browse the repository at this point in the history