Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Wed, 18 Dec 2019 10:18:16 +0000
From: "wangjianjian (C)" <>
To: "" <>
CC: "Songyunlong (Euler)" <>
Subject: [PATCH] ftello: Need adjust file offset before switching to write

Consider below code flow:

FILE *fp = fopen("foobar", "w+");
fputs("hello", fp);
ungetc('x', fp);
fputs("world", fp);
off = ftello(fp);

In this code snippet, 'off' will be 10 at last which should be 5 and
file 'foobar's content will be 'helloworld' which is not correct.

The reason is that when do read, we will try our best to get more data
to fill user-provided and the default stream buffer so that the
underlying file offset may not be consistent with stream offset.
As an example above, 'fgetc' will read the whole 5 bytes from 'foobar'
even though we just would like to read one char.

And when we switch to write, we need to adjust the file offset by
decreasing the size of already buffered but not readed data.

Signed-off-by: Wang Jianjian <>
 src/stdio/__towrite.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/stdio/__towrite.c b/src/stdio/__towrite.c
index 4c9c66ae..dde3c967 100644
--- a/src/stdio/__towrite.c
+++ b/src/stdio/__towrite.c
@@ -7,6 +7,12 @@ int __towrite(FILE *f)
 		f->flags |= F_ERR;
 		return EOF;
+	/* Adjust offset for already buffered but not readed data */
+	if (f->rend - f->rpos > 0 &&
+	    f->seek(f, f->rpos - f->rend, SEEK_CUR) < 0)
+		return EOF;
 	/* Clear read buffer (easier than summoning nasal demons) */
 	f->rpos = f->rend = 0;

Wang Jianjian

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.