diff --git a/src/header/wchar/mod.rs b/src/header/wchar/mod.rs index 514666110e..82380e3642 100644 --- a/src/header/wchar/mod.rs +++ b/src/header/wchar/mod.rs @@ -280,8 +280,15 @@ pub unsafe extern "C" fn ungetwc(wc: wint_t, stream: &mut FILE) -> wint_t { if amount == usize::MAX { return WEOF; } + + /* + We might have unget multiple bytes for a single wchar, eg, `ç` is [195, 167]. + We need to unget them in reversed, so they are pused as [..., 167, 195, ...] + When we do fgetwc, we pop from the Vec, getting the write order of bytes [195, 167]. + If we called ungetc in the non-reversed order, we would get [167, 195] + */ for i in 0..amount { - ungetc(bytes[i] as c_int, &mut *stream); + ungetc(bytes[amount - 1 - i] as c_int, &mut *stream); } wc diff --git a/tests/Makefile b/tests/Makefile index 47a54ada8f..7bd1e8ac8c 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -103,6 +103,7 @@ EXPECT_NAMES=\ unistd/swab \ unistd/write \ waitpid \ + wchar/fgetwc \ wchar/fwide \ wchar/mbrtowc \ wchar/mbsrtowcs \ diff --git a/tests/wchar/ungetwc.c b/tests/wchar/ungetwc.c index 015ba174e7..26f2649a4d 100644 --- a/tests/wchar/ungetwc.c +++ b/tests/wchar/ungetwc.c @@ -3,9 +3,11 @@ #include #include #include - +#include + int main() { + setlocale(LC_ALL, ""); FILE *stream; wint_t wc; wint_t wc2; diff --git a/tests/wchar/ungetwc.in b/tests/wchar/ungetwc.in index 5e6162a566..a86807323c 100644 --- a/tests/wchar/ungetwc.in +++ b/tests/wchar/ungetwc.in @@ -1 +1 @@ -123A \ No newline at end of file +123çA \ No newline at end of file