On Android, I see a test failure: FAIL: test-yesno.sh ===================
test-yesno: write error: Bad address test-yesno: write error: Bad address xout.tmp out.tmp differ: char 1, line 1 test-yesno: write error: Bad address test-yesno: write error: Bad address xout.tmp out.tmp differ: char 1, line 1 test-yesno: write error: Bad address cmp: EOF on out.tmp which is empty FAIL test-yesno.sh (exit status: 1) The cause is that - This test uses atexit (close_stdin); - close_stdin calls fflush (stdin). This uses the Gnulib replacement for fflush. In function update_fpos_cache it overwrites a word of memory past *stdin. Namely the first word of *stdout. - Then, close_stdin calls close_stdout, which calls close_stream (stdout), which calls __fpending (stdout). Since *stdout is not in a valid state, __fpending (stdout) returns a huge value, rather than 0. - close_stream then goes along a wrong control path. This patch fixes it. 2023-01-17 Bruno Haible <br...@clisp.org> fflush: Fix a buffer overrun on 32-bit Android. * lib/stdio-impl.h (fp_): On Android, change the type of _offset to 'long'. * lib/fflush.c (update_fpos_cache): On Android, update a 'long', not an 'fpos_t'. diff --git a/lib/fflush.c b/lib/fflush.c index d38f5f00a3..f3689b3e81 100644 --- a/lib/fflush.c +++ b/lib/fflush.c @@ -99,7 +99,7 @@ update_fpos_cache (_GL_ATTRIBUTE_MAYBE_UNUSED FILE *fp, { # if defined __sferror || defined __DragonFly__ || defined __ANDROID__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ -# if defined __CYGWIN__ +# if defined __CYGWIN__ || defined __ANDROID__ /* fp_->_offset is typed as an integer. */ fp_->_offset = pos; # else diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h index 81e7f83837..89056b0de5 100644 --- a/lib/stdio-impl.h +++ b/lib/stdio-impl.h @@ -96,7 +96,7 @@ unsigned char _nbuf[1]; \ struct { unsigned char *_base; size_t _size; } _lb; \ int _blksize; \ - fpos_t _offset; \ + long _offset; \ /* More fields, not relevant here. */ \ } *) fp) # else