about summary refs log tree commit diff
diff options
context:
space:
mode:
authorShane Murphy <shaneeverittmurphy@gmail.com>2023-05-31 17:22:44 -0700
committerShane Murphy <shaneeverittmurphy@gmail.com>2023-05-31 17:25:53 -0700
commit1293c1720574144ec13df2bbdcf26dab8e3b771f (patch)
tree0a76177c0ace8686894ee09cea401e8ad3ac70d2
parent871b5952023139738f72eba235063575062bc2e9 (diff)
downloadrust-1293c1720574144ec13df2bbdcf26dab8e3b771f.tar.gz
rust-1293c1720574144ec13df2bbdcf26dab8e3b771f.zip
Fix bug in utf16_to_utf8 for zero length strings
This fixes the behavior of sending EOF by pressing Ctrl+Z => Enter in a
windows console.

Previously, that would trip the unpaired surrogate error, whereas now we
correctly detect EOF.
-rw-r--r--library/std/src/sys/windows/stdio.rs7
-rw-r--r--library/std/src/sys/windows/stdio/tests.rs6
2 files changed, 13 insertions, 0 deletions
diff --git a/library/std/src/sys/windows/stdio.rs b/library/std/src/sys/windows/stdio.rs
index 2e3e0859dc1..3fcaaa508e3 100644
--- a/library/std/src/sys/windows/stdio.rs
+++ b/library/std/src/sys/windows/stdio.rs
@@ -11,6 +11,9 @@ use crate::sys::cvt;
 use crate::sys::handle::Handle;
 use core::str::utf8_char_width;
 
+#[cfg(test)]
+mod tests;
+
 // Don't cache handles but get them fresh for every read/write. This allows us to track changes to
 // the value over time (such as if a process calls `SetStdHandle` while it's running). See #40490.
 pub struct Stdin {
@@ -383,6 +386,10 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result<usize> {
     debug_assert!(utf16.len() <= c::c_int::MAX as usize);
     debug_assert!(utf8.len() <= c::c_int::MAX as usize);
 
+    if utf16.is_empty() {
+        return Ok(0);
+    }
+
     let result = unsafe {
         c::WideCharToMultiByte(
             c::CP_UTF8,              // CodePage
diff --git a/library/std/src/sys/windows/stdio/tests.rs b/library/std/src/sys/windows/stdio/tests.rs
new file mode 100644
index 00000000000..1e53e0bee63
--- /dev/null
+++ b/library/std/src/sys/windows/stdio/tests.rs
@@ -0,0 +1,6 @@
+use super::utf16_to_utf8;
+
+#[test]
+fn zero_size_read() {
+    assert_eq!(utf16_to_utf8(&[], &mut []).unwrap(), 0);
+}