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