Original link medium.com/dartlang/da…

Version 2.15 of the Dart SDK adds faster concurrency capabilities, tear-off support for constructors, improvements to Dart: Core library enumeration support, new package-publisher features, and more.

Isolates of concurrent

Today’s physical devices almost all have multi-core cpus capable of performing multiple tasks in parallel, and for most Dart programs, the use of these cores is transparent to the developer:

By default, the Dart runtime runs all Dart code on a single kernel, but uses other kernels to perform system-level tasks, such as asynchronous input/output, reading/writing files, or network calls.

But sometimes the Dart code itself might require concurrent execution scenarios, such as “continuous animation and a long-running task,” or parsing a large JSON file.

If attaching tasks that need to be executed takes too long, it can cause the UI to get stuck or run late, so it is necessary to ensure that the animation can continue to run on the main execution thread without interference by moving these extra tasks to a separate core.

Dart’s concurrency model is based on the design of Computer networks – isolated units of execution. This is to prevent concurrent programming errors associated with shared memory, such as Data Races. And so on.

Dart prevents these errors by not allowing any mutable objects to be shared between Computers, but instead uses messaging to exchange state between Computers, and there are many substantial improvements to Dart 2.15 today.

Dart 2.15 redesigned and implemented the way computers work by introducing a new concept:isolate groupsThe ISOLATE in ISOLATE Groups shares various internal data structures in running programs, making individuals in groups more portable.

Starting extra ISOLates in ISOLATE Groups is now nearly 100 times faster as there is no need to initialize the program structure and the memory required to generate new isolates is 10-100 times less.

Although the ISOLATE Groups still do not allow mutable objects to be shared between the isolates, the groups can be implemented by sharing the heap, thus unlocking more functions such as passing objects from one ISOLATE to another. This can be used to perform tasks that require a large amount of in-memory data to be returned.

For example, get data through network calls, parse the data into a large JSON object, and return the JSON object to the mainframe computer. Performing this operation prior to Dart 2.15 requires “deep copying,” which can lead to UI stuttering if it takes longer than the frame budget.

Computers working in 2.15 can call isolate.exit () to pass the result as an argument. Instead of copying, memory of running computer results is passed to the host, who can receive the results for a specified period of time.

This behavior has also changed to this implementation in the compute() function of update Flutter 2.8. If you are already using isolate.exit () and compute(), These performance improvements will automatically be achieved when you upgrade to Flutter 2.8.

Finally, Dart 2.15 redesigns the implementation of the Debilitating messaging mechanism, increasing the speed of small – and medium-sized messages by about eight times. In addition, it expands the types of objects that can be sent to each other and adds support for function types, closures, and stack trace objects. For more information, see the API documentation sendport.send () :

For more information on how to use isolation, see the introduction to concurrency in the Dart documentation added in 2.15, as well as many code examples to look at.

New language feature: constructor tear-offs

Dart creates a function object that points to a function on another object by using the name of the function, as shown in the following code. The second line of the main() method declares the syntax for “set g to m.Green” :

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!"
}
Copy the code

Such class function Pointers (also called function tear-offs) are common when using Dart core libraries. Here is an example of how foreach() calls iterables by passing function Pointers:

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

In previous versions of the Dart SDK, there was no support for creating tear-offs from constructors (language issue #216). This was annoying because in many cases the tear-offs constructor would be required for development when building Flutter UI. So this syntax is supported starting with Dart 2.15.

Here is an example of building a Column containing three Text widgets by calling.map() and passing it to Text:

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

Text.new refers to the default constructor of the Text class. It can also reference named constructors, such as.map(text.rich).

Related language changes

Dart 2.15 takes the opportunity to fix some inconsistencies in existing function pointer support when implementing the tear-offs of constructors, and can now specialize a generic method to create a non-generic method:

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

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.
Copy the code

Finally, type literals involving generics are cleaned up:

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

Improved enums in the dart:core library

Dart 2.15 adds more optimizations to the enumeration API in the Dart: Core library (#1511), and developers can now retrieve the String value of each enumeration by.name:

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

Enumeration values can also be found by name:

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

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

finalmap = MyEnum.values.asNameMap(); \print(map['three'] == MyEnum.three); // Prints "true".
Copy the code

See Flutter PR #94496 for an example of using these new apis.

Compressed pointers

Dart 2.15 adds support for Compressed, and if only 32-bit address space (up to 4 GB of memory) is needed, the 64-bit SDK can use a more space-saving pointer representation.

Compressing the pointer resulted in a significant memory reduction, and in internal testing of the GPay application, we saw the Dart heap size decrease by approximately 10%.

Since the compressed pointer means that more than 4 GB of RAM cannot be addressed, this feature comes after the configuration option in the Dart SDK and can only be switched by the Dart SDK’s embeddler when the SDK is built.

The Flutter SDK version 2.8 has enabled this configuration for Android builds and the Flutter team is considering enabling this configuration for iOS builds in a future release.

Dart DevTools is included with the Dart SDK

The previous DevTools suite of debugging and performance tools is not included in the Dart SDK, so developers need to download it separately.

Starting with Dart 2.15, DevTools can now be obtained directly from the downloaded Dart SDK without further installation steps.

For more information about using DevTools with the Dart command-line application, see the DevTools documentation.

New pub feature for package publishers

The Dart 2.15 SDK also has two new features in the Dart pub developer command and the pub.dev package repository.

First, package publishers have a new security feature designed to detect secrets (such as Cloud or CI credentials) that publishers accidentally publish in distribution packages.

The Dart SDK was inspired to add this leak detection after learning that thousands of secrets are being leaked in the GitHub repository every day.

Leak detection is run as part of a pre-publish validation run in the DART pub publish command, and if it detects a potential secret in a file that is about to be published, the publish command exits without publishing and prints the following output:

Publishing my_package 1.0.0 to [https://pub.dartlang.org] (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 │ chrysene -BEGIN Private Key -\ 2 │ 53 WMSN H0M6xpM2q + / 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";Copy the code

In rare cases this detection may produce false positives, in which case files can be added to the license whitelist.

Whitelist: dart.dev/go/false-se…

Another feature has been added for publishers: the ability to recall versions of published packages.

When a problematic package version is released, it is often recommended to release a new version in small increments to fix unexpected problems.

In rare cases, such as when a developer does not yet have such a fix capability, or accidentally releases a new major release, the new package recall feature can be used as a last resort, which is available in the admin UI on pub.dev:

When a package version is recalled, the pub client no longer resolves that version for PUB GET or Pub upgrade, and if developers use the successfully withdrawn version (and therefore in their pubspec.lock file), they will see a warning pub at the next run time:

$dart pub get\ Resolving dependencies... \ mypkg 0.0.181-buggy (retracted, 0.0.182-fixed available)\ Got dependencies!Copy the code

Security analysis for detecting bidirectional Unicode characters (CVE-2021–22567)

A general-purpose programming language vulnerability (CVE-2021-42574) involving bidirectional Unicode characters was recently discovered. This vulnerability affects most modern programming languages that support Unicode, as illustrated in the Dart source code below:

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

You might think the program prints You are a regular user, but it might actually print You are an admin. !

This vulnerability can be exploited by using strings that contain bidirectional Unicode characters, such as the characters above, both on a line, to change the orientation of text from left to right to right to left and back.

For bidirectional characters, text rendering on screen is very different from actual text content, as developers can see in GitHub Code Gist for an example.

Mitigation measures for this vulnerability include using tools that detect bidirectional Unicode characters (editors, code review tools, and so on) so that developers can learn about them and knowingly accept their use, and the GitHub GIST file viewer linked above is an example of a tool that displays these characters.

Dart 2.15 introduces further mitigation (Dart Security Bulletin CVE-2021-22567) : The Dart analyzer now scans bidirectional Unicode characters and flags any use of them:

$ dart analyze Analyzing cvetest... Sinfo • 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_literalCopy the code

We recommend replacing these characters with Unicode escape sequences to make them visible in any text editor or viewer, or to disable warnings by adding an override on the line before use if the developer feels that these characters are really being used legally:

// ignore: text_direction_code_point_in_literalCopy the code

Pub. Dev Credentials when using third-party Pub Servers (CVE-2021-22568)

Dart 2.15 also released a second Dart safety bulletin, CVE-2021-22568, related to pub.dev.

This bulletin is intended for package publishers who may be involved in packages that have been published to a third-party distribution server (such as a private or in-house package server). Developers who only publish to the public pub.dev repository (standard configuration) are not affected by this vulnerability.

The vulnerability provides OAuth2 temporary (one hour) access token for authentication in a third party repository if the developer has published to that repository and could be abused to authenticate against the public pub.dev repository.

So a malicious third-party PUB server might use access tokens to impersonate a developer on pub.dev and publish packages there.

If a developer has published a package to an untrusted third party package repository, consider auditing all account activity in the pub.dev public package repository, using the activity log of pub.dev is recommended.