aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--libio/fmemopen.c16
-rw-r--r--stdio-common/tst-fmemopen2.c67
3 files changed, 84 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index acf97b2f98..66a6f02297 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2005-01-05 Ulrich Drepper <drepper@redhat.com>
+ * libio/fmemopen.c (fmemopen_seek): SEEK_END should count from
+ maximum used address, not maximum buffer position.
+
* libio/iofopncook.c (_IO_cookie_seekoff): Define. Mark offset as
invalid to disable optimizations in fileops which won't work here.
(_IO_cookie_jumps): Use it.
diff --git a/libio/fmemopen.c b/libio/fmemopen.c
index 265b848ebe..51e849e846 100644
--- a/libio/fmemopen.c
+++ b/libio/fmemopen.c
@@ -164,7 +164,7 @@ fmemopen_seek (void *cookie, _IO_off64_t *p, int w)
break;
case SEEK_END:
- np = c->size - *p;
+ np = c->maxpos - *p;
break;
default:
@@ -201,6 +201,13 @@ fmemopen (void *buf, size_t len, const char *mode)
cookie_io_functions_t iof;
fmemopen_cookie_t *c;
+ if (len == 0)
+ {
+ einval:
+ __set_errno (EINVAL);
+ return NULL;
+ }
+
c = (fmemopen_cookie_t *) malloc (sizeof (fmemopen_cookie_t));
if (c == NULL)
return NULL;
@@ -218,7 +225,12 @@ fmemopen (void *buf, size_t len, const char *mode)
c->buffer[0] = '\0';
}
else
- c->buffer = buf;
+ {
+ if ((uintptr_t) len > -(uintptr_t) buf)
+ goto einval;
+
+ c->buffer = buf;
+ }
c->size = len;
diff --git a/stdio-common/tst-fmemopen2.c b/stdio-common/tst-fmemopen2.c
new file mode 100644
index 0000000000..6a0ee836a2
--- /dev/null
+++ b/stdio-common/tst-fmemopen2.c
@@ -0,0 +1,67 @@
+#include <assert.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+
+static int
+do_test (void)
+{
+ int result = 0;
+ char buf[100];
+ FILE *fp = fmemopen (buf, sizeof (buf), "w");
+ if (fp == NULL)
+ {
+ puts ("fmemopen failed");
+ return 0;
+ }
+ static const char str[] = "hello world";
+#define nstr (sizeof (str) - 1)
+ fputs (str, fp);
+ off_t o = ftello (fp);
+ if (o != nstr)
+ {
+ printf ("first ftello returned %ld, expected %zu\n", o, nstr);
+ result = 1;
+ }
+ rewind (fp);
+ o = ftello (fp);
+ if (o != 0)
+ {
+ printf ("second ftello returned %ld, expected %zu\n", o, 0);
+ result = 1;
+ }
+ if (fseeko (fp, 0, SEEK_END) != 0)
+ {
+ puts ("fseeko failed");
+ return 1;
+ }
+ o = ftello (fp);
+ if (o != nstr)
+ {
+ printf ("third ftello returned %ld, expected %zu\n", o, nstr);
+ result = 1;
+ }
+ rewind (fp);
+ static const char str2[] = "just hello";
+#define nstr2 (sizeof (str2) - 1)
+ assert (nstr2 < nstr);
+ fputs (str2, fp);
+ o = ftello (fp);
+ if (o != nstr2)
+ {
+ printf ("fourth ftello returned %ld, expected %zu\n", o, nstr2);
+ result = 1;
+ }
+ fclose (fp);
+ static const char str3[] = "just hellod";
+ if (strcmp (buf, str3) != 0)
+ {
+ printf ("final string is \"%s\", expected \"%s\"\n",
+ buf, str3);
+ result = 1;
+ }
+ return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"