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

Crash on format (unwrap() in ropey library) #4038

Closed
v4nderstruck opened this issue Sep 29, 2022 · 3 comments · Fixed by #4047
Closed

Crash on format (unwrap() in ropey library) #4038

v4nderstruck opened this issue Sep 29, 2022 · 3 comments · Fixed by #4047
Labels
A-helix-term Area: Helix term improvements C-bug Category: This is a bug

Comments

@v4nderstruck
Copy link
Contributor

Summary

Helix panics on :format. This is the trace:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Line index out of bounds: line index 92, Rope/RopeSlice line count 87', /Users/brew/Library/Caches/Homebrew/cargo_cache/registry/src/github.com-1ecc6299db9ec823/ropey-1.5.0/src/slice.rs:424:41
stack backtrace:
   0: _rust_begin_unwind
   1: core::panicking::panic_fmt
   2: core::result::unwrap_failed
   3: ropey::slice::RopeSlice::line_to_byte
   4: helix_term::ui::editor::EditorView::doc_syntax_highlights
   5: helix_term::ui::editor::EditorView::render_view
   6: <helix_term::ui::editor::EditorView as helix_term::compositor::Component>::render
   7: helix_term::compositor::Compositor::render
   8: helix_term::application::Application::event_loop_until_idle::{{closure}}
   9: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
  10: std::thread::local::LocalKey<T>::with
  11: tokio::park::thread::CachedParkThread::block_on
  12: tokio::runtime::thread_pool::ThreadPool::block_on
  13: tokio::runtime::Runtime::block_on
  14: hx::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

As you can see, it was caused by the library ropey. I may take a look at this and create a PR :)

Reproduction Steps

  1. touch a new .cpp file ( or use an existing one)
  2. insert the following code (I dont remember where I got it from. It does not really make any sense)
code
int main() {
std::string::const_iterator it;
      std::string::const_iterator temp;

      int state = 0;

      it = uri_string.begin();
      size_t uri_len = uri_string.length();

      if (uri_len >= 7 && std::equal(it, it + 6, "wss://"))
      {
        m_secure = true;
        m_scheme = "wss";
        it += 6;
      }
      else if (uri_len >= 6 && std::equal(it, it + 5, "ws://"))
      {
        m_secure = false;
        m_scheme = "ws";
        it += 5;
      }
      else if (uri_len >= 8 && std::equal(it, it + 7, "http://"))
      {
        m_secure = false;
        m_scheme = "http";
        it += 7;
      }
      else if (uri_len >= 9 && std::equal(it, it + 8, "https://"))
      {
        m_secure = true;
        m_scheme = "https";
        it += 8;
      }
      else
      {
        return;
      }

      // extract host.
      // either a host string
      // an IPv4 address
      // or an IPv6 address
      if (*it == '[')
      {
        ++it;
        // IPv6 literal
        // extract IPv6 digits until ]

        // TODO: this doesn't work on g++... not sure why
        // temp = std::find(it,it2,']');

        temp = it;
        while (temp != uri_string.end())
        {
          if (*temp == ']')
          {
            break;
          }
          ++temp;
        }

        if (temp == uri_string.end())
        {
          return;
        }
        else
        {
          // validate IPv6 literal parts
          // can contain numbers, a-f and A-F
          m_host.append(it, temp);
        }
        it = temp + 1;
        if (it == uri_string.end())
        {
          state = 2;
        }
        else if (*it == '/')
        {
          state = 2;
          ++it;
        }
        else if (*it == ':')
        {
          state = 1;
          ++it;
        }
        else
        {
          // problem
          return;
        }
      }
      else
      {
        // IPv4 or hostname
        // extract until : or /
        while (state == 0)
        {
          if (it == uri_string.end())
          {
            state = 2;
            break;
          }
          else if (*it == '/')
          {
            state = 2;
          }
          else if (*it == ':')
          {
            // end hostname start port
            state = 1;
          }
          else
          {
            m_host += *it;
          }
          ++it;
        }
}

  1. do a :format
  2. crash!

Note that this will not crash if eg. :w and than reopen the file to :format.

Helix log

see crash dump above

Platform

macos

Terminal Emulator

iterm2

Helix Version

helix 22.08.1 (66276ce)

@v4nderstruck v4nderstruck added the C-bug Category: This is a bug label Sep 29, 2022
@kirawi kirawi added the A-helix-term Area: Helix term improvements label Sep 29, 2022
@kirawi
Copy link
Member

kirawi commented Sep 29, 2022

Just to note, it's unlikely that ropey was the cause. The panic is because Helix indexed a Rope out-of-bounds.

@the-mikedavis
Copy link
Member

That one is #2489

@David-Else
Copy link
Contributor

@the-mikedavis I moved the report to that thread and deleted it here.

@the-mikedavis the-mikedavis linked a pull request Oct 1, 2022 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-helix-term Area: Helix term improvements C-bug Category: This is a bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants