Skip to content

Incorrect EOF handling in stdin::lines #112121

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

Closed
ShaneEverittM opened this issue May 31, 2023 · 8 comments · Fixed by #112154
Closed

Incorrect EOF handling in stdin::lines #112121

ShaneEverittM opened this issue May 31, 2023 · 8 comments · Fixed by #112154
Assignees
Labels
C-bug Category: This is a bug. O-windows Operating system: Windows T-libs Relevant to the library team, which will review and decide on the PR/issue.

Comments

@ShaneEverittM
Copy link
Contributor

I tried this code:

use std::io::stdin;

fn main() {
    for line in stdin().lines() {
        let line = line.unwrap();
        println!("{}", line);
    }
}

In windows terminal running Git Bash (also occured in Nushell, though I'm not sure if this is terminal or shell-land), I pressed Ctrl-Z + Enter to send EOF.

I expected to see this happen: The application would gracefully exit the loop

Instead, this happened: I saw this error message:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: InvalidData, message: "Windows stdin in console mode does not support non-UTF-16 input; encountered unpaired surrogate" }', src\main.rs:5:25
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\eof.exe` (exit code: 101)

Meta

rustc --version --verbose:

rustc 1.69.0 (84c898d65 2023-04-16)
binary: rustc
commit-hash: 84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc
commit-date: 2023-04-16
host: x86_64-pc-windows-msvc
release: 1.69.0
LLVM version: 15.0.7
Backtrace

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: InvalidData, message: "Windows stdin in console mode does not support non-UTF-16 input; encountered unpaired surrogate" }', src\main.rs:5:25
stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc/library\std\src\panicking.rs:579
   1: core::panicking::panic_fmt
             at /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc/library\core\src\panicking.rs:64
   2: core::result::unwrap_failed
             at /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc/library\core\src\result.rs:1750
   3: enum2$<core::result::Result<alloc::string::String,std::io::error::Error> >::unwrap<alloc::string::String,std::io::error::Error>
             at /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc\library\core\src\result.rs:1090
   4: eof::main
             at .\src\main.rs:5
   5: core::ops::function::FnOnce::call_once<enum2$<core::result::Result<tuple$<>,std::io::error::Error> > (*)(),tuple$<> >
             at /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc\library\core\src\ops\function.rs:250
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
error: process didn't exit successfully: `target\debug\eof.exe` (exit code: 101)

@ShaneEverittM ShaneEverittM added the C-bug Category: This is a bug. label May 31, 2023
@jyn514 jyn514 added O-windows Operating system: Windows T-libs Relevant to the library team, which will review and decide on the PR/issue. labels May 31, 2023
@ChrisDenton
Copy link
Member

The underlying regression here is that the way we call WideCharToMultiByte does not accept zero length strings. And we're calling ReadConsole in a way that makes ctrl-z immediately return without reading anything after it. This is important because a zero length read is how we signal to stdlib that an eof has occurred (so ctrl-z handling is pretty indirect).

The fix is simple, if anyone wants to claim this issue. This function needs to check for zero length input and immediately return Ok(0) in that case.

@ShaneEverittM
Copy link
Contributor Author

Seems like a good first issue, I can take a stab at it.

@ChrisDenton
Copy link
Member

That would be great!

@ShaneEverittM
Copy link
Contributor Author

Where would be a good place to write a test for this?

@ChrisDenton
Copy link
Member

Hm, this is a Windows specific issue so it should probably stay close to the affected code. Take a look at how alloc.rs uses alloc/tests.rs for tests and do something similar for stdio.

@ShaneEverittM
Copy link
Contributor Author

ShaneEverittM commented May 31, 2023

Hm, this is a Windows specific issue so it should probably stay close to the affected code. Take a look at how alloc.rs uses alloc/tests.rs for tests and do something similar for stdio.

That probably won't work since the function is private, right?
Never mind, I see how things are glued together.

@ChrisDenton
Copy link
Member

It's a sub module so it should be able to access the private functions of its parent (aka super) module. This is noted in the Rust Reference:

If an item is private, it may be accessed by the current module and its descendants.

@ShaneEverittM
Copy link
Contributor Author

It's a sub module so it should be able to access the private functions of its parent (aka super) module. This is noted in the Rust Reference:

If an item is private, it may be accessed by the current module and its descendants.

For sure, just misread the directory structure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. O-windows Operating system: Windows T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants