dart-sdk/tests/corelib_2/string_operator_multiply_test.dart
Stephen Adams 6dd17d6ec4 [runtime] Avoid SIGSEGV on String.*
Correctness changes:

Fix SEGV by checking for overflow in computing the length of the
repeated string.

Performance changes:

Use unnested loops to fill the string instead of nested loops.

Implement `operator *` for _TwoByteString in the same way.

(The default implementation using StringBuffer causes a lot of
allocations. For example, `"α" * 10000` repeatedly adds the small
string to the StringBuffer, which repeatedly compresses a sequence of
small strings to make a bigger string to stop the list of parts
becoming too large. This compression creates a lot of small strings
with the same contents.)

Bug: 49289
Change-Id: I06c3d91b531d7e4fffc8de9f3bada3eb62ad185f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/249122
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
2022-06-19 17:02:41 +00:00

51 lines
1.6 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
main() {
Expect.equals('', 'a' * -11);
Expect.equals('', 'α' * -11);
Expect.equals('', '' * -11);
Expect.equals('', 'a' * 0);
Expect.equals('', 'α' * 0);
Expect.equals('', '' * 0);
Expect.equals('a', 'a' * 1);
Expect.equals('α', 'α' * 1);
Expect.equals('', '' * 1);
Expect.equals('aa', 'a' * 2);
Expect.equals('αα', 'α' * 2);
Expect.equals('∀∀', '' * 2);
Expect.equals('aaa', 'a' * 3);
Expect.equals('ααα', 'α' * 3);
Expect.equals('∀∀∀', '' * 3);
Expect.equals('', '' * 0x4000000000000000);
Expect.throws(() => 'a' * 0x4000000000000000);
Expect.throws(() => 'α' * 0x4000000000000000);
Expect.throws(() => '' * 0x4000000000000000);
for (final string in ['a', 'α', '', 'hello world', 'abc', 'α∀α']) {
for (final count in [0, 1, 10, 100, 255, 256, 257, 1000, 100000]) {
final expected = List.filled(count, string).join();
final actual = string * count;
Expect.equals(expected, actual);
}
}
// http://dartbug.com/49289
Expect.throws(() => 'abcd' * 0x4000000000000000);
Expect.throws(() => 'αxyz' * 0x4000000000000000);
Expect.throws(() => '∀pqr' * 0x4000000000000000);
Expect.throws(() => 'abcd' * (0x4000000000000000 + 1));
Expect.throws(() => 'αxyz' * (0x4000000000000000 + 1));
Expect.throws(() => '∀pqr' * (0x4000000000000000 + 1));
}