Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/newlib
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2006-11-30 00:36:54 +0300
committerJeff Johnston <jjohnstn@redhat.com>2006-11-30 00:36:54 +0300
commitc4c7f13966ecbc0d4047a51fc49720b82cd6c291 (patch)
treee8135d970db17d09fc5fefacc44cae82a91b2d89 /newlib
parent80c6ead24280c15ec859c63ce73924bb948b8323 (diff)
2006-11-29 Eric Blake <ebb9@byu.net>
* libc/stdio/fvwrite.c (__sfvwrite_r): Avoid off-by-one error in asprintf, as well as quadratic realloc behavior.
Diffstat (limited to 'newlib')
-rw-r--r--newlib/ChangeLog7
-rw-r--r--newlib/libc/stdio/fvwrite.c21
2 files changed, 22 insertions, 6 deletions
diff --git a/newlib/ChangeLog b/newlib/ChangeLog
index b86c96282..ff9f034e2 100644
--- a/newlib/ChangeLog
+++ b/newlib/ChangeLog
@@ -1,4 +1,9 @@
-2006-11-29 Kazunori Asayama <asayama@sm.sony.co.jp>
+2006-11-29 Eric Blake <ebb9@byu.net>
+
+ * libc/stdio/fvwrite.c (__sfvwrite_r): Avoid off-by-one error in
+ asprintf, as well as quadratic realloc behavior.
+
+2006-11-29 Kazunori Asayama <asayama@sm.sony.co.jpi
* libc/machine/spu/memset.c: Fix type of explicit cast.
* libc/machine/spu/strncmp.c: Add explicit cast.
diff --git a/newlib/libc/stdio/fvwrite.c b/newlib/libc/stdio/fvwrite.c
index 1cb6e0d1e..ef461d31d 100644
--- a/newlib/libc/stdio/fvwrite.c
+++ b/newlib/libc/stdio/fvwrite.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1990 The Regents of the University of California.
+ * Copyright (c) 1990, 2006 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
@@ -127,13 +127,23 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio),
w = fp->_w;
if (fp->_flags & __SSTR)
{
- if (len > w && fp->_flags & __SMBF)
+ if (len >= w && fp->_flags & __SMBF)
{ /* must be asprintf family */
unsigned char *ptr;
int curpos = (fp->_p - fp->_bf._base);
+ /* Choose a geometric growth factor to avoid
+ quadratic realloc behavior, but use a rate less
+ than (1+sqrt(5))/2 to accomodate malloc
+ overhead. asprintf EXPECTS us to overallocate, so
+ that it can add a trailing \0 without
+ reallocating. The new allocation should thus be
+ max(prev_size*1.5, curpos+len+1). */
+ int newsize = fp->_bf._size * 3 / 2;
+ if (newsize < curpos + len + 1)
+ newsize = curpos + len + 1;
ptr = (unsigned char *)_realloc_r (_REENT,
fp->_bf._base,
- curpos + len);
+ newsize);
if (!ptr)
{
/* Free buffer which is no longer used. */
@@ -142,8 +152,9 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio),
}
fp->_bf._base = ptr;
fp->_p = ptr + curpos;
- fp->_bf._size = curpos + len;
- w = fp->_w = len;
+ fp->_bf._size = newsize;
+ w = len;
+ fp->_w = newsize - curpos;
}
if (len < w)
w = len;