From 5316938142699c5879bbb1ee6393c302bc45385d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 4 Aug 2024 01:04:56 -0700 Subject: [PATCH] Avoid wordsplit quadratic behavior * lib/wordsplit.c (wsplt_assign_var): Avoid unlikely overflow when adding wsp->ws_envidx + n. Avoid quadratic behavior when growing ws_envbuf. --- lib/wordsplit.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/lib/wordsplit.c b/lib/wordsplit.c index 6bf5c191..78071497 100644 --- a/lib/wordsplit.c +++ b/lib/wordsplit.c @@ -1062,7 +1062,7 @@ wsplt_assign_var (struct wordsplit *wsp, char const *name, idx_t namelen, int n = (wsp->ws_flags & WRDSF_ENV_KV) ? 2 : 1; char *v; - if (wsp->ws_envidx + n >= wsp->ws_envsiz) + if (wsp->ws_envsiz - wsp->ws_envidx <= n) { idx_t sz; char **newenv; @@ -1118,13 +1118,24 @@ wsplt_assign_var (struct wordsplit *wsp, char const *name, idx_t namelen, } else { - if (ckd_add (&wsp->ws_envsiz, wsp->ws_envsiz, wsp->ws_envsiz >> 1)) - return _wsplt_nomem (wsp); - newenv = ireallocarray (wsp->ws_envbuf, - wsp->ws_envsiz, sizeof *newenv); - if (!newenv) + idx_t envsiz, envsiz2; + if (ckd_add (&envsiz, wsp->ws_envidx, n + 1)) return _wsplt_nomem (wsp); + newenv = ((!ckd_add (&envsiz2, wsp->ws_envsiz, wsp->ws_envsiz >> 1) + && envsiz < envsiz2) + ? ireallocarray (wsp->ws_envbuf, envsiz2, sizeof *newenv) + : NULL); + if (newenv) + envsiz = envsiz2; + else + { + newenv = ireallocarray (wsp->ws_envbuf, envsiz, sizeof *newenv); + if (!newenv) + return _wsplt_nomem (wsp); + } + wsp->ws_envbuf = newenv; + wsp->ws_envsiz = envsiz; wsp->ws_env = (char const **) wsp->ws_envbuf; } } @@ -1759,14 +1770,15 @@ wordsplit_tildexpand (struct wordsplit *wsp) { if (i > usize) { - char *p = irealloc (uname, i); + if (ckd_add (&usize, usize, usize >> 1) || usize < i) + usize = i; + char *p = irealloc (uname, usize); if (!p) { free (uname); return _wsplt_nomem (wsp); } uname = p; - usize = i; } --i; memcpy (uname, str + 1, i); -- 2.47.2