From a7c8e0cdfba08eff7b118985a1261aa0ac23999a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20H=C3=B8rl=C3=BCck=20Berg?= <36937807+henrikhorluck@users.noreply.github.com> Date: Mon, 17 Jul 2023 14:53:03 +0200 Subject: [PATCH] Fix #9899 integer overflow in string repeat We could end up overflowing if we print out something that's a multiple of the chunk size, which would then finish printing in the chunk-printing, but not break out early. (cherry picked from commit 6325b3662de122b571e33b7121cfc9d172d483bc) --- src/builtins/string.cpp | 5 ++++- tests/checks/string.fish | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/builtins/string.cpp b/src/builtins/string.cpp index 0b1cf8df1..33c131a86 100644 --- a/src/builtins/string.cpp +++ b/src/builtins/string.cpp @@ -1541,7 +1541,7 @@ static int string_repeat(parser_t &parser, io_streams_t &streams, int argc, cons wcstring chunk; chunk.reserve(std::min(chunk_size + w.length(), max)); - for (size_t i = max; i > 0; i -= w.length()) { + for (size_t i = max; i > 0;) { // Build up the chunk. if (i >= w.length()) { chunk.append(w); @@ -1549,6 +1549,9 @@ static int string_repeat(parser_t &parser, io_streams_t &streams, int argc, cons chunk.append(w.substr(0, i)); break; } + + i -= w.length(); + if (chunk.length() >= chunk_size) { // We hit the chunk size, write it repeatedly until we can't anymore. streams.out.append(chunk); diff --git a/tests/checks/string.fish b/tests/checks/string.fish index 52dcec924..8ffeef150 100644 --- a/tests/checks/string.fish +++ b/tests/checks/string.fish @@ -530,6 +530,10 @@ string repeat -n 17 a | string length string repeat -m 5 (string repeat -n 500000 aaaaaaaaaaaaaaaaaa) | string length # CHECK: 5 +# might cause integer overflow +string repeat -n 2999 \n | count +# CHECK: 3000 + # Test equivalent matches with/without the --entire, --regex, and --invert flags. string match -e x abc dxf xyz jkx x z or echo exit 1