diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2006-11-29 21:36:54 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2006-11-29 21:36:54 +0000 |
commit | c4c7f13966ecbc0d4047a51fc49720b82cd6c291 (patch) | |
tree | e8135d970db17d09fc5fefacc44cae82a91b2d89 /newlib | |
parent | 80c6ead24280c15ec859c63ce73924bb948b8323 (diff) | |
download | cygnal-c4c7f13966ecbc0d4047a51fc49720b82cd6c291.tar.gz cygnal-c4c7f13966ecbc0d4047a51fc49720b82cd6c291.tar.bz2 cygnal-c4c7f13966ecbc0d4047a51fc49720b82cd6c291.zip |
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/ChangeLog | 7 | ||||
-rw-r--r-- | newlib/libc/stdio/fvwrite.c | 21 |
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; |