diff options
author | Elliott Hughes <enh@google.com> | 2014-12-01 16:13:30 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2014-12-02 14:22:02 -0800 |
commit | 20841a137beac5caa824e3586c7bd91d879ff92e (patch) | |
tree | 3ccc88081ddcdbe9a4448c462eb16e971007f86e /libc | |
parent | 5cd127d3aa4a2f225be202af01581838fdd3c721 (diff) | |
download | bionic-20841a137beac5caa824e3586c7bd91d879ff92e.zip bionic-20841a137beac5caa824e3586c7bd91d879ff92e.tar.gz bionic-20841a137beac5caa824e3586c7bd91d879ff92e.tar.bz2 |
Avoid pathological behavior in OpenBSD's fread.
Bug: https://code.google.com/p/android/issues/detail?id=81155
Bug: 18556607
Change-Id: Idc60976b79610e2202cc42dc393dcb4ca6c42e05
Diffstat (limited to 'libc')
-rw-r--r-- | libc/Android.mk | 2 | ||||
-rw-r--r-- | libc/stdio/fread.c (renamed from libc/upstream-openbsd/lib/libc/stdio/fread.c) | 18 |
2 files changed, 18 insertions, 2 deletions
diff --git a/libc/Android.mk b/libc/Android.mk index 13fc297..2270dc6 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -58,6 +58,7 @@ libc_common_src_files := \ bionic/sigsetmask.c \ bionic/system_properties_compat.c \ stdio/findfp.c \ + stdio/fread.c \ stdio/snprintf.c\ stdio/sprintf.c \ stdio/stdio_ext.cpp \ @@ -406,7 +407,6 @@ libc_upstream_openbsd_src_files := \ upstream-openbsd/lib/libc/stdio/fputs.c \ upstream-openbsd/lib/libc/stdio/fputwc.c \ upstream-openbsd/lib/libc/stdio/fputws.c \ - upstream-openbsd/lib/libc/stdio/fread.c \ upstream-openbsd/lib/libc/stdio/freopen.c \ upstream-openbsd/lib/libc/stdio/fscanf.c \ upstream-openbsd/lib/libc/stdio/fseek.c \ diff --git a/libc/upstream-openbsd/lib/libc/stdio/fread.c b/libc/stdio/fread.c index 8a592f6..e052128 100644 --- a/libc/upstream-openbsd/lib/libc/stdio/fread.c +++ b/libc/stdio/fread.c @@ -68,7 +68,23 @@ fread(void *buf, size_t size, size_t count, FILE *fp) fp->_r = 0; total = resid; p = buf; - while (resid > (r = fp->_r)) { + + // BEGIN android-added + // Avoid pathological behavior on unbuffered files. OpenBSD + // will loop reading one byte then memcpying one byte! + if ((fp->_flags & __SNBF) != 0) { + // We know if we're unbuffered that our buffer is empty, so + // we can just read directly. + while (resid > 0 && (r = (*fp->_read)(fp->_cookie, p, resid)) > 0) { + p += r; + resid -= r; + } + FUNLOCKFILE(fp); + return ((total - resid) / size); + } + // END android-added + + while (resid > (size_t)(r = fp->_r)) { (void)memcpy((void *)p, (void *)fp->_p, (size_t)r); fp->_p += r; /* fp->_r = 0 ... done in __srefill */ |