Escape HTML attribute for fenced code blocks, in the info string; 2.0.3 (#244)

Escape HTML attribute for fenced code blocks, in the info string; 2.0.3
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 89e2377..56acf1a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,8 @@
 * Render element attributes in the order they were defined.
   Aligns more closely with the strict spec definition.
 * Correctly render `&` within inline image titles.
-* Added 68 new GitHub emojis.
+* Add 68 new GitHub emojis.
+* Escape HTML attribute for fenced code blocks, in the info string.
 
 ## 2.0.2
 
diff --git a/lib/src/block_parser.dart b/lib/src/block_parser.dart
index a07c08a..8153004 100644
--- a/lib/src/block_parser.dart
+++ b/lib/src/block_parser.dart
@@ -443,7 +443,6 @@
 
     var text = childLines.join('\n');
     if (parser.document.encodeHtml) {
-      // Escape the code.
       text = escapeHtml(text);
     }
     var code = Element.text('code', text);
@@ -454,7 +453,13 @@
     if (infoString.isNotEmpty) {
       // only use the first word in the syntax
       // http://spec.commonmark.org/0.22/#example-100
-      infoString = infoString.split(' ').first;
+      var firstSpace = infoString.indexOf(' ');
+      if (firstSpace >= 0) {
+        infoString = infoString.substring(0, firstSpace);
+      }
+      if (parser.document.encodeHtml) {
+        infoString = escapeHtmlAttribute(infoString);
+      }
       code.attributes['class'] = "language-$infoString";
     }
 
diff --git a/lib/src/util.dart b/lib/src/util.dart
index 5b0db05..ea17094 100644
--- a/lib/src/util.dart
+++ b/lib/src/util.dart
@@ -5,6 +5,9 @@
 String escapeHtml(String html) =>
     const HtmlEscape(HtmlEscapeMode.element).convert(html);
 
+String escapeHtmlAttribute(String text) =>
+    const HtmlEscape(HtmlEscapeMode.attribute).convert(text);
+
 // Escape the contents of [value], so that it may be used as an HTML attribute.
 
 // Based on http://spec.commonmark.org/0.28/#backslash-escapes.
diff --git a/lib/src/version.dart b/lib/src/version.dart
index 9f5b2d1..170650c 100644
--- a/lib/src/version.dart
+++ b/lib/src/version.dart
@@ -1,2 +1,2 @@
 // Generated code. Do not modify.
-const packageVersion = '2.0.3-dev';
+const packageVersion = '2.0.3';
diff --git a/pubspec.yaml b/pubspec.yaml
index 670248f..362145c 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: markdown
-version: 2.0.3-dev
+version: 2.0.3
 
 description: A library for converting markdown to HTML.
 author: Dart Team <misc@dartlang.org>
diff --git a/test/markdown_test.dart b/test/markdown_test.dart
index 0c8d598..6cfd500 100644
--- a/test/markdown_test.dart
+++ b/test/markdown_test.dart
@@ -29,6 +29,13 @@
 ''', '''
 <p>5 Ethernet ([Music](</p>
 ''');
+
+    validateCore('Escaping code block language', '''
+```"/><a/href="url">arbitrary_html</a>
+```
+''', '''
+<pre><code class="language-&quot;/&gt;&lt;a/href=&quot;url&quot;&gt;arbitrary_html&lt;/a&gt;"></code></pre>
+''');
   });
 
   group('Resolver', () {
diff --git a/tool/common_mark_stats.json b/tool/common_mark_stats.json
index cfeeb8a..43b001f 100644
--- a/tool/common_mark_stats.json
+++ b/tool/common_mark_stats.json
@@ -244,7 +244,7 @@
   "308": "strict",
   "309": "fail",
   "310": "fail",
-  "311": "loose",
+  "311": "fail",
   "312": "strict",
   "313": "strict"
  },
diff --git a/tool/common_mark_stats.txt b/tool/common_mark_stats.txt
index 7950e3f..5a11e75 100644
--- a/tool/common_mark_stats.txt
+++ b/tool/common_mark_stats.txt
@@ -5,7 +5,7 @@
   22 of   25 –  88.0%  Block quotes
   16 of   17 –  94.1%  Code spans
  124 of  128 –  96.9%  Emphasis and strong emphasis
-  10 of   12 –  83.3%  Entity and numeric character references
+   9 of   12 –  75.0%  Entity and numeric character references
   25 of   28 –  89.3%  Fenced code blocks
   15 of   15 – 100.0%  Hard line breaks
   43 of   43 – 100.0%  HTML blocks
@@ -24,4 +24,4 @@
   11 of   11 – 100.0%  Tabs
    3 of    3 – 100.0%  Textual content
   19 of   19 – 100.0%  Thematic breaks
- 580 of  624 –  92.9%  TOTAL
+ 579 of  624 –  92.8%  TOTAL
diff --git a/tool/gfm_stats.json b/tool/gfm_stats.json
index 3f2cc1e..ae9dd8b 100644
--- a/tool/gfm_stats.json
+++ b/tool/gfm_stats.json
@@ -265,7 +265,7 @@
   "321": "strict",
   "322": "fail",
   "323": "fail",
-  "324": "loose",
+  "324": "fail",
   "325": "strict",
   "326": "strict"
  },
diff --git a/tool/gfm_stats.txt b/tool/gfm_stats.txt
index 1a6f44b..fb5d10e 100644
--- a/tool/gfm_stats.txt
+++ b/tool/gfm_stats.txt
@@ -7,7 +7,7 @@
   20 of   21 –  95.2%  Code spans
    0 of    1 –   0.0%  Disallowed Raw HTML (extension)
  125 of  129 –  96.9%  Emphasis and strong emphasis
-  10 of   12 –  83.3%  Entity and numeric character references
+   9 of   12 –  75.0%  Entity and numeric character references
   25 of   28 –  89.3%  Fenced code blocks
   15 of   15 – 100.0%  Hard line breaks
   43 of   43 – 100.0%  HTML blocks
@@ -28,4 +28,4 @@
   11 of   11 – 100.0%  Tabs
    3 of    3 – 100.0%  Textual content
   19 of   19 – 100.0%  Thematic breaks
- 601 of  654 –  91.9%  TOTAL
+ 600 of  654 –  91.7%  TOTAL