Skip to content

Commit aa53bd0

Browse files
authored
Use wrapJSExceptions() to work around dart-lang/sdk#53105 (#2055)
1 parent e70cd5a commit aa53bd0

File tree

11 files changed

+52
-24
lines changed

11 files changed

+52
-24
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 1.66.1
2+
3+
### JS API
4+
5+
* Fix a bug where Sass compilation could crash in strict mode if passed a
6+
callback that threw a string, boolean, number, symbol, or bignum.
7+
18
## 1.66.0
29

310
* **Breaking change:** Drop support for the additional CSS calculations defined

lib/src/importer/js_to_dart/async.dart

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'dart:async';
66

7+
import 'package:cli_pkg/js.dart';
78
import 'package:node_interop/js.dart';
89
import 'package:node_interop/util.dart';
910

@@ -26,8 +27,8 @@ final class JSToDartAsyncImporter extends AsyncImporter {
2627
JSToDartAsyncImporter(this._canonicalize, this._load);
2728

2829
FutureOr<Uri?> canonicalize(Uri url) async {
29-
var result = _canonicalize(
30-
url.toString(), CanonicalizeOptions(fromImport: fromImport));
30+
var result = wrapJSExceptions(() => _canonicalize(
31+
url.toString(), CanonicalizeOptions(fromImport: fromImport)));
3132
if (isPromise(result)) result = await promiseToFuture(result as Promise);
3233
if (result == null) return null;
3334

@@ -37,7 +38,7 @@ final class JSToDartAsyncImporter extends AsyncImporter {
3738
}
3839

3940
FutureOr<ImporterResult?> load(Uri url) async {
40-
var result = _load(dartToJSUrl(url));
41+
var result = wrapJSExceptions(() => _load(dartToJSUrl(url)));
4142
if (isPromise(result)) result = await promiseToFuture(result as Promise);
4243
if (result == null) return null;
4344

lib/src/importer/js_to_dart/async_file.dart

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'dart:async';
66

7+
import 'package:cli_pkg/js.dart';
78
import 'package:node_interop/js.dart';
89
import 'package:node_interop/util.dart';
910

@@ -32,8 +33,8 @@ final class JSToDartAsyncFileImporter extends AsyncImporter {
3233
FutureOr<Uri?> canonicalize(Uri url) async {
3334
if (url.scheme == 'file') return _filesystemImporter.canonicalize(url);
3435

35-
var result = _findFileUrl(
36-
url.toString(), CanonicalizeOptions(fromImport: fromImport));
36+
var result = wrapJSExceptions(() => _findFileUrl(
37+
url.toString(), CanonicalizeOptions(fromImport: fromImport)));
3738
if (isPromise(result)) result = await promiseToFuture(result as Promise);
3839
if (result == null) return null;
3940
if (!isJSUrl(result)) {

lib/src/importer/js_to_dart/file.dart

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// MIT-style license that can be found in the LICENSE file or at
33
// https://opensource.org/licenses/MIT.
44

5+
import 'package:cli_pkg/js.dart';
56
import 'package:node_interop/js.dart';
67

78
import '../../importer.dart';
@@ -27,8 +28,8 @@ final class JSToDartFileImporter extends Importer {
2728
Uri? canonicalize(Uri url) {
2829
if (url.scheme == 'file') return _filesystemImporter.canonicalize(url);
2930

30-
var result = _findFileUrl(
31-
url.toString(), CanonicalizeOptions(fromImport: fromImport));
31+
var result = wrapJSExceptions(() => _findFileUrl(
32+
url.toString(), CanonicalizeOptions(fromImport: fromImport)));
3233
if (result == null) return null;
3334

3435
if (isPromise(result)) {

lib/src/importer/js_to_dart/sync.dart

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// MIT-style license that can be found in the LICENSE file or at
33
// https://opensource.org/licenses/MIT.
44

5+
import 'package:cli_pkg/js.dart';
56
import 'package:node_interop/js.dart';
67

78
import '../../importer.dart';
@@ -22,8 +23,8 @@ final class JSToDartImporter extends Importer {
2223
JSToDartImporter(this._canonicalize, this._load);
2324

2425
Uri? canonicalize(Uri url) {
25-
var result = _canonicalize(
26-
url.toString(), CanonicalizeOptions(fromImport: fromImport));
26+
var result = wrapJSExceptions(() => _canonicalize(
27+
url.toString(), CanonicalizeOptions(fromImport: fromImport)));
2728
if (result == null) return null;
2829
if (isJSUrl(result)) return jsToDartUrl(result as JSUrl);
2930

@@ -37,7 +38,7 @@ final class JSToDartImporter extends Importer {
3738
}
3839

3940
ImporterResult? load(Uri url) {
40-
var result = _load(dartToJSUrl(url));
41+
var result = wrapJSExceptions(() => _load(dartToJSUrl(url)));
4142
if (result == null) return null;
4243

4344
if (isPromise(result)) {

lib/src/importer/legacy_node/implementation.dart

+9-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'dart:async';
66

7+
import 'package:cli_pkg/js.dart';
78
import 'package:js/js.dart';
89
import 'package:path/path.dart' as p;
910

@@ -97,7 +98,8 @@ final class NodeImporter {
9798
// The previous URL is always an absolute file path for filesystem imports.
9899
var previousString = _previousToString(previous);
99100
for (var importer in _importers) {
100-
if (call2(importer, _renderContext(forImport), url, previousString)
101+
if (wrapJSExceptions(() =>
102+
call2(importer, _renderContext(forImport), url, previousString))
101103
case var value?) {
102104
return _handleImportResult(url, previous, value, forImport);
103105
}
@@ -205,8 +207,12 @@ final class NodeImporter {
205207
String previousString, bool forImport) async {
206208
var completer = Completer<Object>();
207209

208-
var result = call3(importer, _renderContext(forImport), url, previousString,
209-
allowInterop(completer.complete));
210+
var result = wrapJSExceptions(() => call3(
211+
importer,
212+
_renderContext(forImport),
213+
url,
214+
previousString,
215+
allowInterop(completer.complete)));
210216
if (isUndefined(result)) return await completer.future;
211217
return result;
212218
}

lib/src/js/compile.dart

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// MIT-style license that can be found in the LICENSE file or at
33
// https://opensource.org/licenses/MIT.
44

5+
import 'package:cli_pkg/js.dart';
56
import 'package:node_interop/js.dart';
67
import 'package:node_interop/util.dart' hide futureToPromise;
78
import 'package:term_glyph/term_glyph.dart' as glyph;
@@ -274,7 +275,8 @@ List<AsyncCallable> _parseFunctions(Object? functions, {bool asynch = false}) {
274275
if (!asynch) {
275276
late Callable callable;
276277
callable = Callable.fromSignature(signature, (arguments) {
277-
var result = (callback as Function)(toJSArray(arguments));
278+
var result = wrapJSExceptions(
279+
() => (callback as Function)(toJSArray(arguments)));
278280
if (result is Value) return _simplifyValue(result);
279281
if (isPromise(result)) {
280282
throw 'Invalid return value for custom function '
@@ -290,7 +292,8 @@ List<AsyncCallable> _parseFunctions(Object? functions, {bool asynch = false}) {
290292
} else {
291293
late AsyncCallable callable;
292294
callable = AsyncCallable.fromSignature(signature, (arguments) async {
293-
var result = (callback as Function)(toJSArray(arguments));
295+
var result = wrapJSExceptions(
296+
() => (callback as Function)(toJSArray(arguments)));
294297
if (isPromise(result)) {
295298
result = await promiseToFuture<Object>(result as Promise);
296299
}

lib/src/js/legacy.dart

+8-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'dart:convert';
77
import 'dart:js_util';
88
import 'dart:typed_data';
99

10+
import 'package:cli_pkg/js.dart';
1011
import 'package:node_interop/js.dart';
1112
import 'package:path/path.dart' as p;
1213

@@ -217,7 +218,8 @@ List<AsyncCallable> _parseFunctions(RenderOptions options, DateTime start,
217218
scheduleMicrotask(() => currentFiber.run(result));
218219
})
219220
];
220-
var result = (callback as JSFunction).apply(context, jsArguments);
221+
var result = wrapJSExceptions(
222+
() => (callback as JSFunction).apply(context, jsArguments));
221223
return unwrapValue(isUndefined(result)
222224
// Run `fiber.yield()` in runZoned() so that Dart resets the current
223225
// zone once it's done. Otherwise, interweaving fibers can leave
@@ -228,8 +230,9 @@ List<AsyncCallable> _parseFunctions(RenderOptions options, DateTime start,
228230
} else if (!asynch) {
229231
result.add(Callable.fromSignature(
230232
signature.trimLeft(),
231-
(arguments) => unwrapValue((callback as JSFunction)
232-
.apply(context, arguments.map(wrapValue).toList())),
233+
(arguments) => unwrapValue(wrapJSExceptions(() =>
234+
(callback as JSFunction)
235+
.apply(context, arguments.map(wrapValue).toList()))),
233236
requireParens: false));
234237
} else {
235238
result.add(
@@ -239,7 +242,8 @@ List<AsyncCallable> _parseFunctions(RenderOptions options, DateTime start,
239242
...arguments.map(wrapValue),
240243
allowInterop(([Object? result]) => completer.complete(result))
241244
];
242-
var result = (callback as JSFunction).apply(context, jsArguments);
245+
var result = wrapJSExceptions(
246+
() => (callback as JSFunction).apply(context, jsArguments));
243247
return unwrapValue(
244248
isUndefined(result) ? await completer.future : result);
245249
}, requireParens: false));

pkg/sass_api/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 8.2.1
2+
3+
* No user-visible changes.
4+
15
## 8.2.0
26

37
* No user-visible changes.

pkg/sass_api/pubspec.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ name: sass_api
22
# Note: Every time we add a new Sass AST node, we need to bump the *major*
33
# version because it's a breaking change for anyone who's implementing the
44
# visitor interface(s).
5-
version: 8.2.0
5+
version: 8.2.1
66
description: Additional APIs for Dart Sass.
77
homepage: https://github.com/sass/dart-sass
88

99
environment:
1010
sdk: ">=3.0.0 <4.0.0"
1111

1212
dependencies:
13-
sass: 1.66.0
13+
sass: 1.66.1
1414

1515
dev_dependencies:
16-
dartdoc: ^5.0.0
16+
dartdoc: ^6.0.0
1717

1818
dependency_overrides:
1919
sass: { path: ../.. }

pubspec.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: sass
2-
version: 1.66.0
2+
version: 1.66.1
33
description: A Sass implementation in Dart.
44
homepage: https://github.com/sass/dart-sass
55

@@ -14,6 +14,7 @@ dependencies:
1414
args: ^2.0.0
1515
async: ^2.5.0
1616
charcode: ^1.2.0
17+
cli_pkg: ^2.5.0
1718
cli_repl: ^0.2.1
1819
collection: ^1.16.0
1920
http: "^1.1.0"
@@ -38,7 +39,6 @@ dependencies:
3839
dev_dependencies:
3940
analyzer: ">=5.13.0 <7.0.0"
4041
archive: ^3.1.2
41-
cli_pkg: ^2.4.4
4242
crypto: ^3.0.0
4343
dart_style: ^2.0.0
4444
dartdoc: ^6.0.0

0 commit comments

Comments
 (0)