头图

Author/ Michael Thomsen, Dart & Flutter Product Manager, Google

We have officially released version 2.15 of the Dart SDK. This version adds a fast concurrent worker isolate, a new tear-off language feature, improved dart:core library enumeration support, and package Publisher-related new features, etc.

worker isolate the rapid concurrent

Nowadays, almost all modern devices use multi-core CPUs, which can execute multiple tasks in parallel. For most Dart programs, the use of these cores is transparent to the developer: By default, the Dart runtime system runs all Dart code on a single core, but uses other cores to perform system-level tasks , Such as asynchronous input/output, including writing files or calling the network, etc.

However, your own Dart code may also need to run concurrently. For example, you may need to show a continuous animation while performing a long-running task, such as parsing a large JSON file. If the extra task takes too long, it may cause the interface to freeze or delay. If these additional tasks are moved to a separate core, the animation can continue to run on the main execution thread without interference.

Dart's concurrency model is based on isolate , isolate is a mutually isolated independent execution unit, this is to avoid a large number of concurrent programming errors related to shared memory, such as data race conditions and other race conditions . Dart avoids these errors by prohibiting the sharing of any mutable objects between , and uses 161cd12b243918 messaging to exchange state between isolates. In Dart 2.15, we have made many substantial improvements to isolate.

We first redesigned and realized the working method of isolate, and introduced a new concept: isolate group. The isolate in the Isolate group shares various internal data structures, which represent the running program. This makes a single isolate in the group more portable. Now, because there is no need to initialize the program structure, starting an additional isolate in the existing isolate group is more than 100 times faster than before, and the memory consumed by the generated isolate is reduced by 10 to 100 times.

Although the isolate group still prevents shared access to mutable objects between isolates, the isolate group uses a shared heap implementation, which gives it more functions. We can pass objects from one isolate to another isolate, which can be used for worker isolates that perform tasks that return large amounts of memory data. For example, the worker isolate obtains data through network calls, parses the data into a large JSON object graph, and then returns this JSON graph to the main isolate. Before the launch of Dart 2.15, deep copying was required to perform this operation. If the copying time exceeds the frame budget time, it will cause the interface to freeze.

In Dart 2.15, the worker isolate can call Isolate.exit() and pass the result as a parameter. Then, when Dart is running, the memory data containing the results is transferred from the worker isolate to the main isolate without copying, and the main isolate can receive the results within a fixed time. We have updated the compute() Flutter 2.8 to use Isolate.exit(). If you are already using compute(), you will automatically get these performance improvements after upgrading to Flutter 2.8.

Finally, we also redesigned the implementation of the isolate message delivery mechanism, which increased the delivery speed of small and medium-sized messages by approximately 8 times. Sending messages is significantly faster, while receiving messages is almost always completed in a constant time. In addition, we have expanded the types of objects that isolate can send to each other, and added support for function types, closures, and stack trace objects. Please refer to the API documentation of SendPort.send()

To learn more about how to use isolate, please refer to the official document Dart that , and more code examples .

New language feature of

In Dart, you can use the function name to create a function object that points to the function of another object. In the following example, the second row illustrates the main () method will g point m.greet syntax:

class Greeter {
  final String name;
  Greeter(this.name);

  void greet(String who) {
    print('$name says: Hello $who!');
  }
}
void main() {
  final m = Greeter('Michael');
  final g = m.greet; // g holds a function pointer to m.greet.
  g('Leaf'); // Invokes and prints "Michael says: Hello Leaf!"
}

When using the Dart core library, this kind of function pointer (also known as function split ) often appears. The following is an example foreach() on iterable by passing the function pointer:

final m = Greeter('Michael');
['Lasse', 'Bob', 'Erik'].forEach(m.greet);
// Prints "Michael says: Hello Lasse!", "Michael says: Hello Bob!",
// "Michael says: Hello Erik!"

In the previous version, the Dart SDK did not support splitting to create a constructor (language issue #216 ). This is a bit annoying, because in many cases, such as when building a Flutter interface, you need to use the split of the constructor. Starting from Dart 2.15, we support this syntax. The following is a construct comprising three Text the widget Column example of the widget, by calling .map() transmitting Text split constructor to Column subkey.

class FruitWidget extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return Column(
       children: ['Apple', 'Orange'].map(Text.new).toList());
 }
}

Text.new refers to the default constructor of the Text You can also refer to named constructors, such as .map(Text.rich) .

related language changes

When implementing the split of the constructor, we also took this opportunity to fix some inconsistencies in the existing function pointer functions. Now you can specialize generic methods to create non-generic methods:

T id<T>(T value) => value;
var intId = id<int>; // New in 2.15.
int Function(int) intId = id; // Pre-2.15 workaround.

You can even specialize a generic function object to create a non-generic function object:

const fo = id; // Tear off `id`, creating a function object.
const c1 = fo<int>; // New in 2.15; error before.

Finally, Dart 2.15 cleaned up type literals involving generics:

var y = List; // Already supported.
var z = List<int>; // New in 2.15.
var z = typeOf<List<int>>(); // Pre-2.15 workaround.

Improve the enumeration in the dart:core library

We have added many optimizations to the enumeration API of the dart:core library (language issue #1511 ). Now you can .name get each enumeration value String value:

enum MyEnum {
 one, two, three
}
void main() {
 print(MyEnum.one.name);  // Prints "one".
}

You can also find enumeration values by name:

print(MyEnum.values.byName('two') == MyEnum.two);  // Prints "true".

Finally, you can get a mapping of all name-value pairs:

final map = MyEnum.values.asNameMap();
print(map['three'] == MyEnum.three);  // Prints "true".

Please refer to this Flutter PR for examples of the usage of these new APIs.

compressed pointer

Dart 2.15 adds support for compressed pointers, so that if you only need to support a 32-bit address space (up to 4 GB of memory), the 64-bit SDK can use a more space-saving pointer representation. Compressed pointers significantly reduce the memory footprint. In internal tests of the Google Pay application, we found that the volume of the Dart heap has been reduced by about 10%.

Compressed pointer means that it cannot handle more than 4 GB of available RAM, so this feature only exists in the configuration options of the Dart SDK and can only be enabled by the Dart SDK embedder when building the SDK. Flutter SDK version 2.8 is configured to enable this Android build, Flutter team is considering in subsequent editions to build iOS enable this configuration .

Dart SDK includes Dart DevTools

In the past, Dart SDK did not provide debugging and performance tools DevTools kit , you need to download it separately. Starting from Dart 2.15, DevTools will also be obtained when downloading the Dart SDK, no further installation steps are required. For more information about using DevTools in Dart command line applications, please refer to DevTools document .

New pub function for package publishers

Dart 2.15 SDK also added two new functions dart pub developer command and pub.dev

First, a new security feature has been added to the package publisher to detect that the publisher accidentally publishes secrets in the pub package, such as Cloud or CI credentials. In GitHub repo learned in after day, thousands of leaked secret , we decided to add this leak detection.

Leak detection dart pub publish as part of the pre-release verification in the 061cd12b243cd3 command. If it detects a potential secret in the file to be published, the publish command will exit without publishing and print the following output:

Publishing my_package 1.0.0 to https://pub.dartlang.org:
Package validation found the following errors:
* line 1, column 1 of lib/key.pem: Potential leak of Private Key detected.
╷
1 │ ┌ - - -BEGIN PRIVATE KEY - - -
2 │ │ H0M6xpM2q+53wmsN/eYLdgtjgBd3DBmHtPilCkiFICXyaA8z9LkJ
3 │ └ - - -END PRIVATE KEY - - -
╵
* line 2, column 23 of lib/my_package.dart: Potential leak of Google OAuth Refresh Token detected.
╷
2 │ final refreshToken = "1//042ys8uoFwZrkCgYIARAAGAQSNwF-L9IrXmFYE-sfKefSpoCnyqEcsHX97Y90KY-p8TPYPPnY2IPgRXdy0QeVw7URuF5u9oUeIF0";

In rare cases, this detection may cause false positives, marking content or files that you actually intend to publish as potential leaks. In these cases, you can add the file to the permission list .

Secondly, we also added another feature for publishers: revoke the released package version. When a problematic package version is released, our usual recommendation is to release a slightly upgraded new version to fix unexpected problems. But in rare cases, such as if you haven’t fixed these problems, or you accidentally released a major version when you originally planned to release only a minor version, then you can use the new package undo function as a final remedy method. This feature is provided in the management interface of pub.dev:

After the package version is revoked, the pub client will no longer parse the version pub get or pub upgrade If a developer has resolved the revoked version (and it exists in their pubspec.lock file), they will see a warning the pub

$ dart pub get
Resolving dependencies…
mypkg 0.0.181-buggy (retracted, 0.0.182-fixed available)
Got dependencies!

Security Analysis of Detecting Bidirectional Unicode Characters (CVE-2021-22567)

CVE-2021–42574 ) involving bidirectional Unicode characters was recently discovered. This vulnerability affects most modern programming languages that support Unicode. The following Dart source code demonstrates this problem:

main() {
 final accessLevel = 'user';
 if (accessLevel == 'user .⁦// Check if admin⁩ ⁦') {
   print('You are a regular user.');
 } else {
   print('You are an admin.');
 }
}

You might think that the program will print You are a regular user. , but in fact it prints You are an admin. ! By using a string containing bidirectional Unicode characters, you can create this vulnerability. These bidirectional characters are for text on the same line, and the direction of the text can be changed from left to right to right to left, and vice versa. The presentation of bidirectional character text on the screen is completely different from the actual text content. You can take a closer look at this GitHub gist example .

Mitigation measures for this vulnerability include the use of tools that detect bidirectional Unicode characters (editors, code review tools, etc.) so that developers can discover them and use them with knowledge. The GitHub gist file viewer mentioned above is an example of a tool that finds these characters.

Dart 2.15 introduces further mitigation measures ( Dart Security Recommendation CVE-2021-22567 ). Now, the Dart analyzer scans bidirectional Unicode characters and flags any use of them:

$ dart analyze
Analyzing cvetest...                   2.6s
info • bin/cvetest.dart:4:27 • The Unicode code point 'U+202E'
      changes the appearance of text from how it's interpreted
      by the compiler. Try removing the code point or using the
      Unicode escape sequence '\u202E'. •
      text_direction_code_point_in_literal

We recommend replacing these characters with Unicode escape sequences so that they can be displayed in any text editor or viewer. Or, if you do use these characters properly, you can add an overwrite statement before the line of code that uses these characters to disable the warning:

// ignore: text_direction_code_point_in_literal

pub.dev credential vulnerability when using a third-party pub server (CVE-2021-22568)

We also released the second Dart security recommendation related to pub.dev: CVE-2021-22568 . This recommendation is for package publishers who may publish packages to third-party pub package servers (such as private or company internal package servers). who only released the package to the public pub.dev repo (standard configuration) is not affected by this vulnerability .

If you have published the package to a third-party repo, the vulnerability is: The OAuth2 temporary (one hour) access token used to authenticate in the third-party repo may be misused to authenticate on the public pub.dev repo . Therefore, a malicious third-party pub server may use the access token to impersonate you on pub.dev and publish the package. If you have published your package to an untrusted third-party package repo, please consider reviewing all activities of your account on the pub.dev public package repo. We recommend that you use pub.dev activity log to view.

last

Hope you like the new features in Dart 2.15 that has launched This is our last version this year, and we would like to take this opportunity to express our gratitude to the wonderful Dart ecosystem. Thank you for your valuable feedback and your continued support. Thank you pub.dev in the past year. They have enriched our ecosystem. We are eagerly looking forward to working again next year, and we plan to launch a lot of exciting content in 2022. I wish you all a happy new year and enjoy the upcoming holidays!


Flutter
350 声望2.5k 粉丝

Flutter 为应用开发带来了革新: 只要一套代码库,即可构建、测试和发布适用于移动、Web、桌面和嵌入式平台的精美应用。Flutter 中文开发者网站 flutter.cn