Merge pull request #19 from denesalmasi/yaml

The yaml scanner hung in an infinite loop when trying to scan this
string: "{" (a single opening brace).

_fetchMoreTokens kept growing the token list with a STREAM_END token ad
infinitum.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index da7f6bd..a60773b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.1.11
+
+* Fix an infinite loop when parsing some invalid documents.
+
 ## 2.1.10
 
 * Support `string_scanner` 1.0.0.
diff --git a/lib/src/scanner.dart b/lib/src/scanner.dart
index b1ae1e3..9bf8114 100644
--- a/lib/src/scanner.dart
+++ b/lib/src/scanner.dart
@@ -324,6 +324,9 @@
       if (_tokens.isNotEmpty) {
         _staleSimpleKeys();
 
+        // If there are no more tokens to fetch, break.
+        if (_tokens.last.type == TokenType.STREAM_END) break;
+
         // If the current token could be a simple key, we need to scan more
         // tokens until we determine whether it is or not. Otherwise we might
         // not emit the `KEY` token before we emit the value of the key.
diff --git a/pubspec.yaml b/pubspec.yaml
index 990054f..cc622c4 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: yaml
-version: 2.1.10
+version: 2.1.11
 author: "Dart Team <misc@dartlang.org>"
 homepage: https://github.com/dart-lang/yaml
 description: A parser for YAML.
diff --git a/test/yaml_test.dart b/test/yaml_test.dart
index 153af5e..8da4b8a 100644
--- a/test/yaml_test.dart
+++ b/test/yaml_test.dart
@@ -29,26 +29,33 @@
     });
   });
 
-  group("refuses documents that declare version", () {
-    test("1.0", () {
-      expectYamlFails("""
+  group("refuses", () {
+    // Regression test for #19.
+    test("invalid contents", () {
+      expectYamlFails("{");
+    });
+
+    group("documents that declare version", () {
+      test("1.0", () {
+        expectYamlFails("""
          %YAML 1.0
          --- text
          """);
-    });
+      });
 
-    test("1.3", () {
-      expectYamlFails("""
-         %YAML 1.3
-         --- text
-         """);
-    });
+      test("1.3", () {
+        expectYamlFails("""
+           %YAML 1.3
+           --- text
+           """);
+      });
 
-    test("2.0", () {
-      expectYamlFails("""
-         %YAML 2.0
-         --- text
-         """);
+      test("2.0", () {
+        expectYamlFails("""
+           %YAML 2.0
+           --- text
+           """);
+      });
     });
   });