Skip to content

Commit 83343d7

Browse files
authored
Fix a race condition in meta.load-css() (#1376)
We weren't properly awaiting a call to CssStylesheet.accept(), which meant that it could try to continue doing work asynchronously in the wrong context. Closes #1318
1 parent 713b7cc commit 83343d7

File tree

5 files changed

+21
-7
lines changed

5 files changed

+21
-7
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
* Fix an edge case where `@extend` wouldn't affect a selector within a
1717
pseudo-selector such as `:is()` that itself extended other selectors.
1818

19+
* Fix a race condition where `meta.load-css()` could trigger an internal error
20+
when running in asynchronous mode.
21+
1922
## 1.35.1
2023

2124
* Fix a bug where the quiet dependency flag didn't silence warnings in some

lib/src/extend/extension_store.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,7 @@ class ExtensionStore {
262262
_extensionsByExtender.putIfAbsent(simple, () => []).add(extension);
263263
// Only source specificity for the original selector is relevant.
264264
// Selectors generated by `@extend` don't get new specificity.
265-
_sourceSpecificity.putIfAbsent(
266-
simple, () => complex.maxSpecificity);
265+
_sourceSpecificity.putIfAbsent(simple, () => complex.maxSpecificity);
267266
}
268267

269268
if (selectors != null || existingExtensions != null) {

lib/src/visitor/async_evaluate.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ class _EvaluateVisitor
592592
/// The [stackFrame] and [nodeWithSpan] are used for the name and location of
593593
/// the stack frame for the duration of the [callback].
594594
Future<void> _loadModule(Uri url, String stackFrame, AstNode nodeWithSpan,
595-
void callback(Module module),
595+
FutureOr<void> callback(Module module),
596596
{Uri? baseUrl,
597597
Configuration? configuration,
598598
bool namesInErrors = false}) async {
@@ -606,7 +606,7 @@ class _EvaluateVisitor
606606
configuration.nodeWithSpan.span);
607607
}
608608

609-
_addExceptionSpan(nodeWithSpan, () => callback(builtInModule));
609+
await _addExceptionSpanAsync(nodeWithSpan, () => callback(builtInModule));
610610
return;
611611
}
612612

@@ -643,7 +643,7 @@ class _EvaluateVisitor
643643
}
644644

645645
try {
646-
callback(module);
646+
await callback(module);
647647
} on SassRuntimeException {
648648
rethrow;
649649
} on MultiSpanSassException catch (error) {
@@ -3212,7 +3212,7 @@ class _EvaluateVisitor
32123212

32133213
/// Like [_addExceptionSpan], but for an asynchronous [callback].
32143214
Future<T> _addExceptionSpanAsync<T>(
3215-
AstNode nodeWithSpan, Future<T> callback()) async {
3215+
AstNode nodeWithSpan, FutureOr<T> callback()) async {
32163216
try {
32173217
return await callback();
32183218
} on MultiSpanSassScriptException catch (error) {

lib/src/visitor/evaluate.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// DO NOT EDIT. This file was generated from async_evaluate.dart.
66
// See tool/grind/synchronize.dart for details.
77
//
8-
// Checksum: 1249b1184a46950409776772cb1c6003b80ebb31
8+
// Checksum: b36c6c618b222a025ed67c1df8afb66e037a132b
99
//
1010
// ignore_for_file: unused_import
1111

test/dart_api_test.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,4 +225,16 @@ a {
225225
});
226226
});
227227
});
228+
229+
// Regression test for #1318
230+
test("meta.load-module() doesn't have a race condition", () async {
231+
await d.file("other.scss", '/**//**/').create();
232+
expect(compileStringAsync("""
233+
@use 'sass:meta';
234+
@include meta.load-css("other.scss");
235+
""", loadPaths: [d.sandbox]), completion(equals("/**/\n/**/")));
236+
237+
// Give the race condition time to appear.
238+
await pumpEventQueue();
239+
});
228240
}

0 commit comments

Comments
 (0)