[glibc] stdio-common: Remove fallback realloc calls from vfscanf
Florian Weimer via Glibc-cvs <[email protected]>
| Newsgroups | gmane.comp.lib.glibc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=6467136459cc86a4426e35ac8d8f9de4673b9f1f commit 6467136459cc86a4426e35ac8d8f9de4673b9f1f Author: Florian Weimer <[email protected]> Date: Thu Aug 20 09:20:55 2026 +0200 stdio-common: Remove fallback realloc calls from vfscanf These merely delay the inevitable on 32-bit architectures. Growing a buffer one character at a time is very slow, so this could lead to even more processing time for very large inputs. Reviewed-by: Collin Funk <[email protected]> Diff: --- stdio-common/vfscanf-internal.c | 316 +++++++++++----------------------------- 1 file changed, 82 insertions(+), 234 deletions(-) diff --git a/stdio-common/vfscanf-internal.c b/stdio-common/vfscanf-internal.c index e2e08c0eab..a15669f056 100644 --- a/stdio-common/vfscanf-internal.c +++ b/stdio-common/vfscanf-internal.c @@ -825,21 +825,9 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, newstr = (char *) realloc (*strptr, strsize * 2); if (newstr == NULL) { - /* Can't allocate that much. Last-ditch effort. */ - newstr = (char *) realloc (*strptr, - strleng + MB_LEN_MAX); - if (newstr == NULL) - { - /* c can't have `a' flag, only `m'. */ - done = EOF; - goto errout; - } - else - { - *strptr = newstr; - str = newstr + strleng; - strsize = strleng + MB_LEN_MAX; - } + /* c can't have `a' flag, only `m'. */ + done = EOF; + goto errout; } else { @@ -874,21 +862,9 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, str = (char *) realloc (*strptr, newsize); if (str == NULL) { - /* Can't allocate that much. Last-ditch - effort. */ - str = (char *) realloc (*strptr, strsize + 1); - if (str == NULL) - { - /* c can't have `a' flag, only `m'. */ - done = EOF; - goto errout; - } - else - { - *strptr = (char *) str; - str += strsize; - ++strsize; - } + /* c can't have `a' flag, only `m'. */ + done = EOF; + goto errout; } else { @@ -949,23 +925,9 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, sizeof (wchar_t)); if (wstr == NULL) { - /* Can't allocate that much. Last-ditch effort. */ - wstr = (wchar_t *) - __libc_reallocarray (*strptr, strsize + 1, - sizeof (wchar_t)); - if (wstr == NULL) - { - /* C or lc can't have `a' flag, only `m' - flag. */ - done = EOF; - goto errout; - } - else - { - *strptr = (char *) wstr; - wstr += strsize; - ++strsize; - } + /* C or lc can't have `a' flag, only `m' flag. */ + done = EOF; + goto errout; } else { @@ -1004,22 +966,9 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, sizeof (wchar_t)); if (wstr == NULL) { - /* Can't allocate that much. Last-ditch effort. */ - wstr = (wchar_t *) - __libc_reallocarray (*strptr, strsize + 1, - sizeof (wchar_t)); - if (wstr == NULL) - { - /* C or lc can't have `a' flag, only `m' flag. */ - done = EOF; - goto errout; - } - else - { - *strptr = (char *) wstr; - wstr += strsize; - ++strsize; - } + /* C or lc can't have `a' flag, only `m' flag. */ + done = EOF; + goto errout; } else { @@ -1120,31 +1069,18 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, newstr = (char *) realloc (*strptr, strsize * 2); if (newstr == NULL) { - /* Can't allocate that much. Last-ditch - effort. */ - newstr = (char *) realloc (*strptr, - strleng + MB_LEN_MAX); - if (newstr == NULL) - { - if (flags & POSIX_MALLOC) - { - done = EOF; - goto errout; - } - /* We lose. Oh well. Terminate the - string and stop converting, - so at least we don't skip any input. */ - ((char *) (*strptr))[strleng] = '\0'; - strptr = NULL; - ++done; - conv_error (); - } - else + if (flags & POSIX_MALLOC) { - *strptr = newstr; - str = newstr + strleng; - strsize = strleng + MB_LEN_MAX; + done = EOF; + goto errout; } + /* We lose. Oh well. Terminate the + string and stop converting, + so at least we don't skip any input. */ + ((char *) (*strptr))[strleng] = '\0'; + strptr = NULL; + ++done; + conv_error (); } else { @@ -1176,30 +1112,18 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, str = (char *) realloc (*strptr, newsize); if (str == NULL) { - /* Can't allocate that much. Last-ditch - effort. */ - str = (char *) realloc (*strptr, strsize + 1); - if (str == NULL) - { - if (flags & POSIX_MALLOC) - { - done = EOF; - goto errout; - } - /* We lose. Oh well. Terminate the - string and stop converting, - so at least we don't skip any input. */ - ((char *) (*strptr))[strsize - 1] = '\0'; - strptr = NULL; - ++done; - conv_error (); - } - else + if (flags & POSIX_MALLOC) { - *strptr = (char *) str; - str += strsize; - ++strsize; + done = EOF; + goto errout; } + /* We lose. Oh well. Terminate the + string and stop converting, + so at least we don't skip any input. */ + ((char *) (*strptr))[strsize - 1] = '\0'; + strptr = NULL; + ++done; + conv_error (); } else { @@ -1309,32 +1233,18 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, (*strptr, newsize, sizeof (wchar_t)); if (wstr == NULL) { - /* Can't allocate that much. Last-ditch - effort. */ - wstr = (wchar_t *) - __libc_reallocarray (*strptr, strsize + 1, - sizeof (wchar_t)); - if (wstr == NULL) + if (flags & POSIX_MALLOC) { - if (flags & POSIX_MALLOC) - { - done = EOF; - goto errout; - } - /* We lose. Oh well. Terminate the string - and stop converting, so at least we don't - skip any input. */ - ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; - strptr = NULL; - ++done; - conv_error (); - } - else - { - *strptr = (char *) wstr; - wstr += strsize; - ++strsize; + done = EOF; + goto errout; } + /* We lose. Oh well. Terminate the string + and stop converting, so at least we don't + skip any input. */ + ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; + strptr = NULL; + ++done; + conv_error (); } else { @@ -1387,31 +1297,18 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, sizeof (wchar_t)); if (wstr == NULL) { - /* Can't allocate that much. Last-ditch effort. */ - wstr = (wchar_t *) - __libc_reallocarray (*strptr, strsize + 1, - sizeof (wchar_t)); - if (wstr == NULL) - { - if (flags & POSIX_MALLOC) - { - done = EOF; - goto errout; - } - /* We lose. Oh well. Terminate the - string and stop converting, so at - least we don't skip any input. */ - ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; - strptr = NULL; - ++done; - conv_error (); - } - else + if (flags & POSIX_MALLOC) { - *strptr = (char *) wstr; - wstr += strsize; - ++strsize; + done = EOF; + goto errout; } + /* We lose. Oh well. Terminate the + string and stop converting, so at + least we don't skip any input. */ + ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; + strptr = NULL; + ++done; + conv_error (); } else { @@ -2804,32 +2701,18 @@ digits_extended_fail: (*strptr, newsize, sizeof (wchar_t)); if (wstr == NULL) { - /* Can't allocate that much. Last-ditch - effort. */ - wstr = (wchar_t *) - __libc_reallocarray (*strptr, strsize + 1, - sizeof (wchar_t)); - if (wstr == NULL) - { - if (flags & POSIX_MALLOC) - { - done = EOF; - goto errout; - } - /* We lose. Oh well. Terminate the string - and stop converting, so at least we don't - skip any input. */ - ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; - strptr = NULL; - ++done; - conv_error (); - } - else + if (flags & POSIX_MALLOC) { - *strptr = (char *) wstr; - wstr += strsize; - ++strsize; + done = EOF; + goto errout; } + /* We lose. Oh well. Terminate the string + and stop converting, so at least we don't + skip any input. */ + ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; + strptr = NULL; + ++done; + conv_error (); } else { @@ -2890,32 +2773,18 @@ digits_extended_fail: (*strptr, newsize, sizeof (wchar_t)); if (wstr == NULL) { - /* Can't allocate that much. Last-ditch - effort. */ - wstr = (wchar_t *) - __libc_reallocarray (*strptr, strsize + 1, - sizeof (wchar_t)); - if (wstr == NULL) - { - if (flags & POSIX_MALLOC) - { - done = EOF; - goto errout; - } - /* We lose. Oh well. Terminate the - string and stop converting, - so at least we don't skip any input. */ - ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; - strptr = NULL; - ++done; - conv_error (); - } - else + if (flags & POSIX_MALLOC) { - *strptr = (char *) wstr; - wstr += strsize; - ++strsize; + done = EOF; + goto errout; } + /* We lose. Oh well. Terminate the + string and stop converting, + so at least we don't skip any input. */ + ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; + strptr = NULL; + ++done; + conv_error (); } else { @@ -3039,31 +2908,18 @@ digits_extended_fail: newstr = (char *) realloc (*strptr, 2 * strsize); if (newstr == NULL) { - /* Can't allocate that much. Last-ditch - effort. */ - newstr = (char *) realloc (*strptr, - strleng + MB_LEN_MAX); - if (newstr == NULL) - { - if (flags & POSIX_MALLOC) - { - done = EOF; - goto errout; - } - /* We lose. Oh well. Terminate the string - and stop converting, so at least we don't - skip any input. */ - ((char *) (*strptr))[strleng] = '\0'; - strptr = NULL; - ++done; - conv_error (); - } - else + if (flags & POSIX_MALLOC) { - *strptr = newstr; - str = newstr + strleng; - strsize = strleng + MB_LEN_MAX; + done = EOF; + goto errout; } + /* We lose. Oh well. Terminate the string + and stop converting, so at least we don't + skip any input. */ + ((char *) (*strptr))[strleng] = '\0'; + strptr = NULL; + ++done; + conv_error (); } else { @@ -3102,17 +2958,9 @@ digits_extended_fail: /* Enlarge the buffer. */ size_t newsize = grow_to_fit (strsize, width); - allocagain: str = (char *) realloc (*strptr, newsize); if (str == NULL) { - /* Can't allocate that much. Last-ditch - effort. */ - if (newsize > strsize + 1) - { - newsize = strsize + 1; - goto allocagain; - } if (flags & POSIX_MALLOC) { done = EOF;