diff --git a/CHANGELOG.md b/CHANGELOG.md index a34e52f9a..7364c1b7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,11 +21,15 @@ `\E9clair` are parsed to the same value. See [the proposal][identifier-escapes] for details. +* Don't choke on a [byte-order mark][] at the beginning of a document when + running in JavaScript. + [math functions]: https://drafts.csswg.org/css-values/#math-function [css-import]: https://github.com/sass/language/blob/master/accepted/css-imports.md [css-min-max]: https://github.com/sass/language/blob/master/accepted/min-max.md [media-ranges]: https://github.com/sass/language/blob/master/accepted/media-ranges.md [identifier-escapes]: https://github.com/sass/language/blob/master/accepted/identifier-escapes.md +[byte-order mark]: https://en.wikipedia.org/wiki/Byte_order_mark ### Command-Line Interface diff --git a/lib/src/parse/stylesheet.dart b/lib/src/parse/stylesheet.dart index 6885cabee..32c32167a 100644 --- a/lib/src/parse/stylesheet.dart +++ b/lib/src/parse/stylesheet.dart @@ -65,6 +65,8 @@ abstract class StylesheetParser extends Parser { Stylesheet parse() { return wrapSpanFormatException(() { var start = scanner.state; + // Allow a byte-order mark at the beginning of the document. + scanner.scanChar(0xFEFF); var statements = this.statements(() => _statement(root: true)); scanner.expectDone(); return new Stylesheet(statements, scanner.spanFrom(start), diff --git a/test/cli/shared.dart b/test/cli/shared.dart index 8da3badad..0dfd67361 100644 --- a/test/cli/shared.dart +++ b/test/cli/shared.dart @@ -3,6 +3,7 @@ // https://opensource.org/licenses/MIT. import 'dart:async'; +import 'dart:io'; import 'package:path/path.dart' as p; import 'package:test/test.dart'; @@ -44,6 +45,15 @@ void sharedTests(Future runSass(Iterable arguments)) { await sass.shouldExit(0); }); + // Regression test for #437. + test("compiles a Sass file with a BOM to CSS", () async { + await d.file("test.scss", "\uFEFF\$color: red;").create(); + + var sass = await runSass(["test.scss"]); + expect(sass.stdout, emitsDone); + await sass.shouldExit(0); + }); + // On Windows, this verifies that we don't consider the colon after a drive // letter to be an `input:output` separator. test("compiles an absolute Sass file to CSS", () async {