<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[210280] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/210280">210280</a></dd>
<dt>Author</dt> <dd>wilander@apple.com</dd>
<dt>Date</dt> <dd>2017-01-04 11:21:42 -0800 (Wed, 04 Jan 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Validate the BCP47-ness of the language string passed to TrackBase::setLanguage()
https://bugs.webkit.org/show_bug.cgi?id=123926

Reviewed by Jer Noble.

LayoutTests/imported/w3c:

* web-platform-tests/html/dom/reflection-embedded-expected.txt:
    Expected text change since we now have console warnings for
    invalid language tags.
* web-platform-tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/srclang-expected.txt:
    Expected text change since we now have console warnings for
    invalid language tags.
* web-platform-tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/language-expected.txt:
    Expected text change since we now have console warnings for
    invalid language tags.

Source/WebCore:

Test: media/media-source/only-bcp47-language-tags-accepted-as-valid.html

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::configureTextTrackGroup):
    Log message now includes the valid BCP 47 language too.
(WebCore::HTMLMediaElement::setSelectedTextTrack):
    Now sets preferred language to the valid BCP 47 language.
* html/track/TextTrack.cpp:
(WebCore::TextTrack::setLanguage):
    Removed fixme and aligned comments with new behavior.
* html/track/TrackBase.cpp:
(WebCore::TrackBase::TrackBase):
    Initializes m_validBCP47Language with language parameter.
(WebCore::isValidBCP47LanguageTag):
    New convenience function.
(WebCore::TrackBase::setLanguage):
    Sets m_validBCP47Language if the incoming tag is valid.
    Produces a console warning if the tag is invalid.
    The member m_language is set to the incoming tag regardless.
(WebCore::TrackBase::validBCP47Language):
    New getter for valid language tag. To be used internally.
* html/track/TrackBase.h:
    New AtomicString member m_validBCP47Language.
(WebCore::TrackBase::setLanguage): Deleted.
* html/track/VideoTrack.cpp:
(WebCore::VideoTrack::setLanguage):
    Removed fixme and aligned comments with new behavior.
* page/CaptionUserPreferences.cpp:
(WebCore::trackDisplayName):
    Now uses the getter for BCP 47 language.
(WebCore::CaptionUserPreferences::textTrackLanguageSelectionScore):
    Now uses the getter for BCP 47 language.
* page/CaptionUserPreferencesMediaAF.cpp:
(WebCore::buildDisplayStringForTrackBase):
    Now uses the getter for BCP 47 language.
(WebCore::CaptionUserPreferencesMediaAF::textTrackSelectionScore):
    Now uses the getter for BCP 47 language.
(WebCore::textTrackCompare):
    Now uses the getter for BCP 47 language.
(WebCore::CaptionUserPreferencesMediaAF::sortedTrackListForMenu):
    Now uses the getter for BCP 47 language.

LayoutTests:

* media/media-source/only-bcp47-language-tags-accepted-as-valid-expected.txt: Added.
* media/media-source/only-bcp47-language-tags-accepted-as-valid.html: Added.
* media/track/w3c/interfaces/HTMLTrackElement/srclang-expected.txt:
    Expected text change since we now have console warnings for
    invalid language tags.
* media/track/w3c/interfaces/TextTrack/language-expected.txt:
    Expected text change since we now have console warnings for
    invalid language tags.
* platform/ios-simulator-wk2/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt:
    Expected text change since we now have console warnings for
    invalid language tags.
* platform/ios-simulator/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt:
    Expected text change since we now have console warnings for
    invalid language tags.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cChangeLog">trunk/LayoutTests/imported/w3c/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestshtmldomreflectionembeddedexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestshtmlsemanticsembeddedcontentmediaelementsinterfacesHTMLElementHTMLTrackElementsrclangexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/srclang-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestshtmlsemanticsembeddedcontentmediaelementsinterfacesTextTracklanguageexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/language-expected.txt</a></li>
<li><a href="#trunkLayoutTestsmediatrackw3cinterfacesHTMLTrackElementsrclangexpectedtxt">trunk/LayoutTests/media/track/w3c/interfaces/HTMLTrackElement/srclang-expected.txt</a></li>
<li><a href="#trunkLayoutTestsmediatrackw3cinterfacesTextTracklanguageexpectedtxt">trunk/LayoutTests/media/track/w3c/interfaces/TextTrack/language-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformiossimulatorimportedw3cwebplatformtestshtmldomreflectionembeddedexpectedtxt">trunk/LayoutTests/platform/ios-simulator/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformiossimulatorwk2importedw3cwebplatformtestshtmldomreflectionembeddedexpectedtxt">trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementcpp">trunk/Source/WebCore/html/HTMLMediaElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackTextTrackcpp">trunk/Source/WebCore/html/track/TextTrack.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackTrackBasecpp">trunk/Source/WebCore/html/track/TrackBase.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackTrackBaseh">trunk/Source/WebCore/html/track/TrackBase.h</a></li>
<li><a href="#trunkSourceWebCorehtmltrackVideoTrackcpp">trunk/Source/WebCore/html/track/VideoTrack.cpp</a></li>
<li><a href="#trunkSourceWebCorepageCaptionUserPreferencescpp">trunk/Source/WebCore/page/CaptionUserPreferences.cpp</a></li>
<li><a href="#trunkSourceWebCorepageCaptionUserPreferencesMediaAFcpp">trunk/Source/WebCore/page/CaptionUserPreferencesMediaAF.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsmediamediasourceonlybcp47languagetagsacceptedasvalidexpectedtxt">trunk/LayoutTests/media/media-source/only-bcp47-language-tags-accepted-as-valid-expected.txt</a></li>
<li><a href="#trunkLayoutTestsmediamediasourceonlybcp47languagetagsacceptedasvalidhtml">trunk/LayoutTests/media/media-source/only-bcp47-language-tags-accepted-as-valid.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/LayoutTests/ChangeLog        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2017-01-04  John Wilander  &lt;wilander@apple.com&gt;
+
+        Validate the BCP47-ness of the language string passed to TrackBase::setLanguage()
+        https://bugs.webkit.org/show_bug.cgi?id=123926
+
+        Reviewed by Jer Noble.
+
+        * media/media-source/only-bcp47-language-tags-accepted-as-valid-expected.txt: Added.
+        * media/media-source/only-bcp47-language-tags-accepted-as-valid.html: Added.
+        * media/track/w3c/interfaces/HTMLTrackElement/srclang-expected.txt:
+            Expected text change since we now have console warnings for
+            invalid language tags.
+        * media/track/w3c/interfaces/TextTrack/language-expected.txt:
+            Expected text change since we now have console warnings for
+            invalid language tags.
+        * platform/ios-simulator-wk2/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt:
+            Expected text change since we now have console warnings for
+            invalid language tags.
+        * platform/ios-simulator/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt:
+            Expected text change since we now have console warnings for
+            invalid language tags.
+
</ins><span class="cx"> 2017-01-04  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Cross Origin importScripts() scripts lack source URL, causes issues with Inspector showing Resource
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/ChangeLog (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/ChangeLog        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/LayoutTests/imported/w3c/ChangeLog        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2017-01-04  John Wilander  &lt;wilander@apple.com&gt;
+
+        Validate the BCP47-ness of the language string passed to TrackBase::setLanguage()
+        https://bugs.webkit.org/show_bug.cgi?id=123926
+
+        Reviewed by Jer Noble.
+
+        * web-platform-tests/html/dom/reflection-embedded-expected.txt:
+            Expected text change since we now have console warnings for
+            invalid language tags.
+        * web-platform-tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/srclang-expected.txt:
+            Expected text change since we now have console warnings for
+            invalid language tags.
+        * web-platform-tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/language-expected.txt:
+            Expected text change since we now have console warnings for
+            invalid language tags.
+
</ins><span class="cx"> 2017-01-03  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Make setting Event's cancelBubble to false a no-op
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestshtmldomreflectionembeddedexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -6,6 +6,32 @@
</span><span class="cx"> Blocked access to external URL http://site.example/path???@#l
</span><span class="cx"> Blocked access to external URL http://site.example/
</span><span class="cx"> Blocked access to external URL http://site.example/path???@#l
</span><ins>+CONSOLE MESSAGE: line 707: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'undefined' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language '7' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language '1.5' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'true' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'false' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language '[object Object]' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language '-Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'null' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'test-toString' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'test-valueOf' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'undefined' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language '7' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language '1.5' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'true' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'false' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language '[object Object]' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language '-Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'null' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'test-toString' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'test-valueOf' is not a valid BCP 47 language tag.
</ins><span class="cx"> Implementers looking to fix bugs might want to use the original version of this suite's test framework, which conveniently aggregates similar errors and only reports failures. This file is (part of) the authoritative conformance test suite, and is suitable for incorporation into automated test suites.
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestshtmlsemanticsembeddedcontentmediaelementsinterfacesHTMLElementHTMLTrackElementsrclangexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/srclang-expected.txt (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/srclang-expected.txt        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/srclang-expected.txt        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -1,3 +1,9 @@
</span><ins>+CONSOLE MESSAGE: line 43: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 64: The language ' foo 
+' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language ' foo 
+' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language contains a null character and is not a valid BCP 47 language tag.
</ins><span class="cx"> 
</span><span class="cx"> PASS HTMLTrackElement.srclang missing value 
</span><span class="cx"> PASS HTMLTrackElement.srclang empty string content attribute 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestshtmlsemanticsembeddedcontentmediaelementsinterfacesTextTracklanguageexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/language-expected.txt (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/language-expected.txt        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/language-expected.txt        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -1,3 +1,5 @@
</span><ins>+CONSOLE MESSAGE: line 1380: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 26: The language contains a null character and is not a valid BCP 47 language tag.
</ins><span class="cx"> 
</span><span class="cx"> PASS TextTrack.language 
</span><span class="cx"> PASS TextTrack.language, \u0000 
</span></span></pre></div>
<a id="trunkLayoutTestsmediamediasourceonlybcp47languagetagsacceptedasvalidexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/media-source/only-bcp47-language-tags-accepted-as-valid-expected.txt (0 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-source/only-bcp47-language-tags-accepted-as-valid-expected.txt                                (rev 0)
+++ trunk/LayoutTests/media/media-source/only-bcp47-language-tags-accepted-as-valid-expected.txt        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -0,0 +1,302 @@
</span><ins>+CONSOLE MESSAGE: line 176: The language 'a' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language 'a' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'a' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language '1' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language '1' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language '1' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'ab-abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language 'ab-abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'ab-abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language '1a' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language '1a' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language '1a' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language '-a' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language '-a' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language '-a' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'a-' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language 'a-' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'a-' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'a1' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language 'a1' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'a1' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'aa1' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language 'aa1' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'aa1' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'aaaa' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language 'aaaa' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'aaaa' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'aaa1' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language 'aaa1' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'aaa1' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'inv-alid-char space' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language 'inv-alid-char space' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'inv-alid-char space' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'inv-alid-char–longDash' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language 'inv-alid-char–longDash' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'inv-alid-char–longDash' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'inv-alid-char-PÃ¥lska' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language 'inv-alid-char-PÃ¥lska' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'inv-alid-char-PÃ¥lska' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'inv-alid-char-*' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language 'inv-alid-char-*' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'inv-alid-char-*' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'inv-alid-char-' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 106: The language 'inv-alid-char-' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 176: The language 'inv-alid-char-' is not a valid BCP 47 language tag.
+Test that only BCP47 language tags are accepted as valid but still reflected.
+
+
+RUN(video.src = URL.createObjectURL(source))
+EVENT(sourceopen)
+RUN(source.duration = loader.duration())
+RUN(sourceBuffer = source.addSourceBuffer(loader.type()))
+RUN(sourceBuffer.appendBuffer(loader.initSegment()))
+EVENT(update)
+Append a partial media segment.
+RUN(sourceBuffer.appendBuffer(loader.mediaSegment(0).slice(0, loader.mediaSegment(0).byteLength / 2)))
+EVENT(update)
+EXPECTED (videoTrack.language == 'en-GB-oed') OK
+EXPECTED (textTrack.track.language == 'en-GB-oed') OK
+EXPECTED (audioTrack.language == 'en-GB-oed') OK
+EXPECTED (videoTrack.language == 'i-ami') OK
+EXPECTED (textTrack.track.language == 'i-ami') OK
+EXPECTED (audioTrack.language == 'i-ami') OK
+EXPECTED (videoTrack.language == 'i-bnn') OK
+EXPECTED (textTrack.track.language == 'i-bnn') OK
+EXPECTED (audioTrack.language == 'i-bnn') OK
+EXPECTED (videoTrack.language == 'i-default') OK
+EXPECTED (textTrack.track.language == 'i-default') OK
+EXPECTED (audioTrack.language == 'i-default') OK
+EXPECTED (videoTrack.language == 'i-enochian') OK
+EXPECTED (textTrack.track.language == 'i-enochian') OK
+EXPECTED (audioTrack.language == 'i-enochian') OK
+EXPECTED (videoTrack.language == 'i-hak') OK
+EXPECTED (textTrack.track.language == 'i-hak') OK
+EXPECTED (audioTrack.language == 'i-hak') OK
+EXPECTED (videoTrack.language == 'i-klingon') OK
+EXPECTED (textTrack.track.language == 'i-klingon') OK
+EXPECTED (audioTrack.language == 'i-klingon') OK
+EXPECTED (videoTrack.language == 'i-lux') OK
+EXPECTED (textTrack.track.language == 'i-lux') OK
+EXPECTED (audioTrack.language == 'i-lux') OK
+EXPECTED (videoTrack.language == 'i-mingo') OK
+EXPECTED (textTrack.track.language == 'i-mingo') OK
+EXPECTED (audioTrack.language == 'i-mingo') OK
+EXPECTED (videoTrack.language == 'i-navajo') OK
+EXPECTED (textTrack.track.language == 'i-navajo') OK
+EXPECTED (audioTrack.language == 'i-navajo') OK
+EXPECTED (videoTrack.language == 'i-pwn') OK
+EXPECTED (textTrack.track.language == 'i-pwn') OK
+EXPECTED (audioTrack.language == 'i-pwn') OK
+EXPECTED (videoTrack.language == 'i-tao') OK
+EXPECTED (textTrack.track.language == 'i-tao') OK
+EXPECTED (audioTrack.language == 'i-tao') OK
+EXPECTED (videoTrack.language == 'i-tay') OK
+EXPECTED (textTrack.track.language == 'i-tay') OK
+EXPECTED (audioTrack.language == 'i-tay') OK
+EXPECTED (videoTrack.language == 'i-tsu') OK
+EXPECTED (textTrack.track.language == 'i-tsu') OK
+EXPECTED (audioTrack.language == 'i-tsu') OK
+EXPECTED (videoTrack.language == 'sgn-BE-FR') OK
+EXPECTED (textTrack.track.language == 'sgn-BE-FR') OK
+EXPECTED (audioTrack.language == 'sgn-BE-FR') OK
+EXPECTED (videoTrack.language == 'sgn-BE-NL') OK
+EXPECTED (textTrack.track.language == 'sgn-BE-NL') OK
+EXPECTED (audioTrack.language == 'sgn-BE-NL') OK
+EXPECTED (videoTrack.language == 'sgn-CH-DE') OK
+EXPECTED (textTrack.track.language == 'sgn-CH-DE') OK
+EXPECTED (audioTrack.language == 'sgn-CH-DE') OK
+EXPECTED (videoTrack.language == 'art-lojban') OK
+EXPECTED (textTrack.track.language == 'art-lojban') OK
+EXPECTED (audioTrack.language == 'art-lojban') OK
+EXPECTED (videoTrack.language == 'cel-gaulish') OK
+EXPECTED (textTrack.track.language == 'cel-gaulish') OK
+EXPECTED (audioTrack.language == 'cel-gaulish') OK
+EXPECTED (videoTrack.language == 'no-bok') OK
+EXPECTED (textTrack.track.language == 'no-bok') OK
+EXPECTED (audioTrack.language == 'no-bok') OK
+EXPECTED (videoTrack.language == 'no-nyn') OK
+EXPECTED (textTrack.track.language == 'no-nyn') OK
+EXPECTED (audioTrack.language == 'no-nyn') OK
+EXPECTED (videoTrack.language == 'zh-guoyu') OK
+EXPECTED (textTrack.track.language == 'zh-guoyu') OK
+EXPECTED (audioTrack.language == 'zh-guoyu') OK
+EXPECTED (videoTrack.language == 'zh-hakka') OK
+EXPECTED (textTrack.track.language == 'zh-hakka') OK
+EXPECTED (audioTrack.language == 'zh-hakka') OK
+EXPECTED (videoTrack.language == 'zh-min') OK
+EXPECTED (textTrack.track.language == 'zh-min') OK
+EXPECTED (audioTrack.language == 'zh-min') OK
+EXPECTED (videoTrack.language == 'zh-min-nan') OK
+EXPECTED (textTrack.track.language == 'zh-min-nan') OK
+EXPECTED (audioTrack.language == 'zh-min-nan') OK
+EXPECTED (videoTrack.language == 'zh-xiang') OK
+EXPECTED (textTrack.track.language == 'zh-xiang') OK
+EXPECTED (audioTrack.language == 'zh-xiang') OK
+EXPECTED (videoTrack.language == 'de') OK
+EXPECTED (textTrack.track.language == 'de') OK
+EXPECTED (audioTrack.language == 'de') OK
+EXPECTED (videoTrack.language == 'fr') OK
+EXPECTED (textTrack.track.language == 'fr') OK
+EXPECTED (audioTrack.language == 'fr') OK
+EXPECTED (videoTrack.language == 'ja') OK
+EXPECTED (textTrack.track.language == 'ja') OK
+EXPECTED (audioTrack.language == 'ja') OK
+EXPECTED (videoTrack.language == 'zh-Hant') OK
+EXPECTED (textTrack.track.language == 'zh-Hant') OK
+EXPECTED (audioTrack.language == 'zh-Hant') OK
+EXPECTED (videoTrack.language == 'zh-Han') OK
+EXPECTED (textTrack.track.language == 'zh-Han') OK
+EXPECTED (audioTrack.language == 'zh-Han') OK
+EXPECTED (videoTrack.language == 'sr-Cyrl') OK
+EXPECTED (textTrack.track.language == 'sr-Cyrl') OK
+EXPECTED (audioTrack.language == 'sr-Cyrl') OK
+EXPECTED (videoTrack.language == 'sr-Latn') OK
+EXPECTED (textTrack.track.language == 'sr-Latn') OK
+EXPECTED (audioTrack.language == 'sr-Latn') OK
+EXPECTED (videoTrack.language == 'zh-cmn-Hans-CN') OK
+EXPECTED (textTrack.track.language == 'zh-cmn-Hans-CN') OK
+EXPECTED (audioTrack.language == 'zh-cmn-Hans-CN') OK
+EXPECTED (videoTrack.language == 'cmn-Hans-CN') OK
+EXPECTED (textTrack.track.language == 'cmn-Hans-CN') OK
+EXPECTED (audioTrack.language == 'cmn-Hans-CN') OK
+EXPECTED (videoTrack.language == 'zh-yue-HK') OK
+EXPECTED (textTrack.track.language == 'zh-yue-HK') OK
+EXPECTED (audioTrack.language == 'zh-yue-HK') OK
+EXPECTED (videoTrack.language == 'yue-HK') OK
+EXPECTED (textTrack.track.language == 'yue-HK') OK
+EXPECTED (audioTrack.language == 'yue-HK') OK
+EXPECTED (videoTrack.language == 'zh-Hans-CN') OK
+EXPECTED (textTrack.track.language == 'zh-Hans-CN') OK
+EXPECTED (audioTrack.language == 'zh-Hans-CN') OK
+EXPECTED (videoTrack.language == 'sr-Latn-RS') OK
+EXPECTED (textTrack.track.language == 'sr-Latn-RS') OK
+EXPECTED (audioTrack.language == 'sr-Latn-RS') OK
+EXPECTED (videoTrack.language == 'sl-rozaj') OK
+EXPECTED (textTrack.track.language == 'sl-rozaj') OK
+EXPECTED (audioTrack.language == 'sl-rozaj') OK
+EXPECTED (videoTrack.language == 'sl-rozaj-biske') OK
+EXPECTED (textTrack.track.language == 'sl-rozaj-biske') OK
+EXPECTED (audioTrack.language == 'sl-rozaj-biske') OK
+EXPECTED (videoTrack.language == 'sl-nedis') OK
+EXPECTED (textTrack.track.language == 'sl-nedis') OK
+EXPECTED (audioTrack.language == 'sl-nedis') OK
+EXPECTED (videoTrack.language == 'de-CH-1901') OK
+EXPECTED (textTrack.track.language == 'de-CH-1901') OK
+EXPECTED (audioTrack.language == 'de-CH-1901') OK
+EXPECTED (videoTrack.language == 'sl-IT-nedis') OK
+EXPECTED (textTrack.track.language == 'sl-IT-nedis') OK
+EXPECTED (audioTrack.language == 'sl-IT-nedis') OK
+EXPECTED (videoTrack.language == 'hy-Latn-IT-arevela') OK
+EXPECTED (textTrack.track.language == 'hy-Latn-IT-arevela') OK
+EXPECTED (audioTrack.language == 'hy-Latn-IT-arevela') OK
+EXPECTED (videoTrack.language == 'en-US') OK
+EXPECTED (textTrack.track.language == 'en-US') OK
+EXPECTED (audioTrack.language == 'en-US') OK
+EXPECTED (videoTrack.language == 'es-419') OK
+EXPECTED (textTrack.track.language == 'es-419') OK
+EXPECTED (audioTrack.language == 'es-419') OK
+EXPECTED (videoTrack.language == 'de-CH-x-phonebk') OK
+EXPECTED (textTrack.track.language == 'de-CH-x-phonebk') OK
+EXPECTED (audioTrack.language == 'de-CH-x-phonebk') OK
+EXPECTED (videoTrack.language == 'az-Arab-x-AZE-derbend') OK
+EXPECTED (textTrack.track.language == 'az-Arab-x-AZE-derbend') OK
+EXPECTED (audioTrack.language == 'az-Arab-x-AZE-derbend') OK
+EXPECTED (videoTrack.language == 'x-whatever') OK
+EXPECTED (textTrack.track.language == 'x-whatever') OK
+EXPECTED (audioTrack.language == 'x-whatever') OK
+EXPECTED (videoTrack.language == 'qaa-Qaaa-QM-x-southern') OK
+EXPECTED (textTrack.track.language == 'qaa-Qaaa-QM-x-southern') OK
+EXPECTED (audioTrack.language == 'qaa-Qaaa-QM-x-southern') OK
+EXPECTED (videoTrack.language == 'de-Qaaa') OK
+EXPECTED (textTrack.track.language == 'de-Qaaa') OK
+EXPECTED (audioTrack.language == 'de-Qaaa') OK
+EXPECTED (videoTrack.language == 'sr-Latn-QM') OK
+EXPECTED (textTrack.track.language == 'sr-Latn-QM') OK
+EXPECTED (audioTrack.language == 'sr-Latn-QM') OK
+EXPECTED (videoTrack.language == 'sr-Qaaa-RS') OK
+EXPECTED (textTrack.track.language == 'sr-Qaaa-RS') OK
+EXPECTED (audioTrack.language == 'sr-Qaaa-RS') OK
+EXPECTED (videoTrack.language == 'zh-Hant-CN-x-private1-private2') OK
+EXPECTED (textTrack.track.language == 'zh-Hant-CN-x-private1-private2') OK
+EXPECTED (audioTrack.language == 'zh-Hant-CN-x-private1-private2') OK
+EXPECTED (videoTrack.language == 'de-DE') OK
+EXPECTED (textTrack.track.language == 'de-DE') OK
+EXPECTED (audioTrack.language == 'de-DE') OK
+EXPECTED (videoTrack.language == 'de-de') OK
+EXPECTED (textTrack.track.language == 'de-de') OK
+EXPECTED (audioTrack.language == 'de-de') OK
+EXPECTED (videoTrack.language == 'de-Latn-DE') OK
+EXPECTED (textTrack.track.language == 'de-Latn-DE') OK
+EXPECTED (audioTrack.language == 'de-Latn-DE') OK
+EXPECTED (videoTrack.language == 'de-Latf-DE') OK
+EXPECTED (textTrack.track.language == 'de-Latf-DE') OK
+EXPECTED (audioTrack.language == 'de-Latf-DE') OK
+EXPECTED (videoTrack.language == 'de-DE-x-goethe') OK
+EXPECTED (textTrack.track.language == 'de-DE-x-goethe') OK
+EXPECTED (audioTrack.language == 'de-DE-x-goethe') OK
+EXPECTED (videoTrack.language == 'de-Latn-DE-1996') OK
+EXPECTED (textTrack.track.language == 'de-Latn-DE-1996') OK
+EXPECTED (audioTrack.language == 'de-Latn-DE-1996') OK
+EXPECTED (videoTrack.language == 'de-Deva-DE') OK
+EXPECTED (textTrack.track.language == 'de-Deva-DE') OK
+EXPECTED (audioTrack.language == 'de-Deva-DE') OK
+EXPECTED (videoTrack.language == 'en-US-u-islamcal') OK
+EXPECTED (textTrack.track.language == 'en-US-u-islamcal') OK
+EXPECTED (audioTrack.language == 'en-US-u-islamcal') OK
+EXPECTED (videoTrack.language == 'zh-CN-a-myext-x-private') OK
+EXPECTED (textTrack.track.language == 'zh-CN-a-myext-x-private') OK
+EXPECTED (audioTrack.language == 'zh-CN-a-myext-x-private') OK
+EXPECTED (videoTrack.language == 'en-a-myext-b-another') OK
+EXPECTED (textTrack.track.language == 'en-a-myext-b-another') OK
+EXPECTED (audioTrack.language == 'en-a-myext-b-another') OK
+EXPECTED (videoTrack.language == 'zh-Latn-CN-variant1-a-extend1-x-wadegile-private1') OK
+EXPECTED (textTrack.track.language == 'zh-Latn-CN-variant1-a-extend1-x-wadegile-private1') OK
+EXPECTED (audioTrack.language == 'zh-Latn-CN-variant1-a-extend1-x-wadegile-private1') OK
+EXPECTED (videoTrack.language == 'a') OK
+EXPECTED (textTrack.track.language == 'a') OK
+EXPECTED (audioTrack.language == 'a') OK
+EXPECTED (videoTrack.language == '1') OK
+EXPECTED (textTrack.track.language == '1') OK
+EXPECTED (audioTrack.language == '1') OK
+EXPECTED (videoTrack.language == 'ab-abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij') OK
+EXPECTED (textTrack.track.language == 'ab-abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij') OK
+EXPECTED (audioTrack.language == 'ab-abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij') OK
+EXPECTED (videoTrack.language == '1a') OK
+EXPECTED (textTrack.track.language == '1a') OK
+EXPECTED (audioTrack.language == '1a') OK
+EXPECTED (videoTrack.language == '-a') OK
+EXPECTED (textTrack.track.language == '-a') OK
+EXPECTED (audioTrack.language == '-a') OK
+EXPECTED (videoTrack.language == 'a-') OK
+EXPECTED (textTrack.track.language == 'a-') OK
+EXPECTED (audioTrack.language == 'a-') OK
+EXPECTED (videoTrack.language == 'a1') OK
+EXPECTED (textTrack.track.language == 'a1') OK
+EXPECTED (audioTrack.language == 'a1') OK
+EXPECTED (videoTrack.language == 'aa1') OK
+EXPECTED (textTrack.track.language == 'aa1') OK
+EXPECTED (audioTrack.language == 'aa1') OK
+EXPECTED (videoTrack.language == 'aaaa') OK
+EXPECTED (textTrack.track.language == 'aaaa') OK
+EXPECTED (audioTrack.language == 'aaaa') OK
+EXPECTED (videoTrack.language == 'aaa1') OK
+EXPECTED (textTrack.track.language == 'aaa1') OK
+EXPECTED (audioTrack.language == 'aaa1') OK
+EXPECTED (videoTrack.language == 'inv-alid-char space') OK
+EXPECTED (textTrack.track.language == 'inv-alid-char space') OK
+EXPECTED (audioTrack.language == 'inv-alid-char space') OK
+EXPECTED (videoTrack.language == 'inv-alid-char–longDash') OK
+EXPECTED (textTrack.track.language == 'inv-alid-char–longDash') OK
+EXPECTED (audioTrack.language == 'inv-alid-char–longDash') OK
+EXPECTED (videoTrack.language == 'inv-alid-char-PÃ¥lska') OK
+EXPECTED (textTrack.track.language == 'inv-alid-char-PÃ¥lska') OK
+EXPECTED (audioTrack.language == 'inv-alid-char-PÃ¥lska') OK
+EXPECTED (videoTrack.language == 'inv-alid-char-*') OK
+EXPECTED (textTrack.track.language == 'inv-alid-char-*') OK
+EXPECTED (audioTrack.language == 'inv-alid-char-*') OK
+EXPECTED (videoTrack.language == 'inv-alid-char-') OK
+EXPECTED (textTrack.track.language == 'inv-alid-char-') OK
+EXPECTED (audioTrack.language == 'inv-alid-char-') OK
+END OF TEST
+
</ins></span></pre></div>
<a id="trunkLayoutTestsmediamediasourceonlybcp47languagetagsacceptedasvalidhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/media-source/only-bcp47-language-tags-accepted-as-valid.html (0 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-source/only-bcp47-language-tags-accepted-as-valid.html                                (rev 0)
+++ trunk/LayoutTests/media/media-source/only-bcp47-language-tags-accepted-as-valid.html        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -0,0 +1,131 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;title&gt;Test that only BCP47 language tags are accepted as valid but still reflected&lt;/title&gt;
+        &lt;!--
+        &lt;script src=&quot;media-controls.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;media-file.js&quot;&gt;&lt;/script&gt;
+        --&gt;
+        &lt;script src=&quot;media-source-loader.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;../video-test.js&quot;&gt;&lt;/script&gt;
+        &lt;script&gt;
+            var loader;
+            var source;
+            var sourceBuffer;
+
+            function mediaDataLoadingFailed() {
+                failTest('Media data loading failed');
+            }
+
+            function mediaDataLoaded() {
+                source = new MediaSource();
+                waitForEvent('sourceopen', sourceOpen, false, false, source);
+                waitForEventAndFail('error');
+                run('video.src = URL.createObjectURL(source)');
+            }
+
+            function sourceOpen() {
+                run('source.duration = loader.duration()');
+                run('sourceBuffer = source.addSourceBuffer(loader.type())');
+                waitForEventOn(sourceBuffer, 'update', sourceInitialized, false, true);
+                run('sourceBuffer.appendBuffer(loader.initSegment())');
+            }
+
+            function sourceInitialized() {
+                waitForEventOn(sourceBuffer, 'update', startBCP74Test, false, true);
+                consoleWrite('Append a partial media segment.')
+                run('sourceBuffer.appendBuffer(loader.mediaSegment(0).slice(0, loader.mediaSegment(0).byteLength / 2))');
+            }
+
+            if (window.testRunner)
+                testRunner.dumpAsText();
+
+            var validLanguageTags = [
+                // Grandfathered, irregular, https://tools.ietf.org/html/bcp47#section-2.1
+                &quot;en-GB-oed&quot;, &quot;i-ami&quot;, &quot;i-bnn&quot;, &quot;i-default&quot;,
+                &quot;i-enochian&quot;, &quot;i-hak&quot;, &quot;i-klingon&quot;, &quot;i-lux&quot;,
+                &quot;i-mingo&quot;, &quot;i-navajo&quot;, &quot;i-pwn&quot;, &quot;i-tao&quot;,
+                &quot;i-tay&quot;, &quot;i-tsu&quot;, &quot;sgn-BE-FR&quot;, &quot;sgn-BE-NL&quot;,
+                &quot;sgn-CH-DE&quot;,
+                // Grandfathered, regular, https://tools.ietf.org/html/bcp47#section-2.1
+                &quot;art-lojban&quot;, &quot;cel-gaulish&quot;, &quot;no-bok&quot;, &quot;no-nyn&quot;,
+                &quot;zh-guoyu&quot;, &quot;zh-hakka&quot;, &quot;zh-min&quot;, &quot;zh-min-nan&quot;,
+                &quot;zh-xiang&quot;,
+                // Other examples from the spec, mainly https://tools.ietf.org/html/bcp47#appendix-A
+                &quot;de&quot;, &quot;fr&quot;, &quot;ja&quot;, &quot;zh-Hant&quot;,
+                &quot;zh-Han&quot;, &quot;sr-Cyrl&quot;, &quot;sr-Latn&quot;, &quot;zh-cmn-Hans-CN&quot;,
+                &quot;cmn-Hans-CN&quot;, &quot;zh-yue-HK&quot;, &quot;yue-HK&quot;, &quot;zh-Hans-CN&quot;,
+                &quot;sr-Latn-RS&quot;, &quot;sl-rozaj&quot;, &quot;sl-rozaj-biske&quot;, &quot;sl-nedis&quot;,
+                &quot;de-CH-1901&quot;, &quot;sl-IT-nedis&quot;, &quot;hy-Latn-IT-arevela&quot;, &quot;en-US&quot;,
+                &quot;es-419&quot;, &quot;de-CH-x-phonebk&quot;, &quot;az-Arab-x-AZE-derbend&quot;, &quot;x-whatever&quot;,
+                &quot;qaa-Qaaa-QM-x-southern&quot;, &quot;de-Qaaa&quot;, &quot;sr-Latn-QM&quot;, &quot;sr-Qaaa-RS&quot;,
+                &quot;zh-Hant-CN-x-private1-private2&quot;, &quot;de-DE&quot;, &quot;de-de&quot;, &quot;de-Latn-DE&quot;,
+                &quot;de-Latf-DE&quot;, &quot;de-DE-x-goethe&quot;, &quot;de-Latn-DE-1996&quot;, &quot;de-Deva-DE&quot;,
+                &quot;en-US-u-islamcal&quot;, &quot;zh-CN-a-myext-x-private&quot;, &quot;en-a-myext-b-another&quot;,
+                &quot;zh-Latn-CN-variant1-a-extend1-x-wadegile-private1&quot;
+            ];
+
+            var invalidLanguageTags = [
+                // Invalid length, less than 2 or over 100
+                &quot;a&quot;, &quot;1&quot;, &quot;ab-abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij&quot;,
+                // Invalid first characters
+                &quot;1a&quot;, &quot;-a&quot;,
+                // Invalid second characters
+                &quot;a-&quot;, &quot;a1&quot;,
+                // Invalid third characters
+                &quot;aa1&quot;,
+                // Invalid fourth characters
+                &quot;aaaa&quot;, &quot;aaa1&quot;,
+                // Invalid characters beyond the fourth
+                &quot;inv-alid-char space&quot;, &quot;inv-alid-char–longDash&quot;, &quot;inv-alid-char-Pålska&quot;,
+                &quot;inv-alid-char-*&quot;, &quot;inv-alid-char-&quot;
+            ];
+
+            var videoTrack;
+            var audioTrack;
+            var textTrack;
+            function startBCP74Test () {
+                videoTrack = video.videoTracks[0];
+                audioTrack = video.audioTracks[0];
+                // Access text track language through the element's srclang attribute
+                // since the DOM property is read-only.
+                textTrack = document.getElementById(&quot;textTrack&quot;);
+                for (var i = 0; i &lt; validLanguageTags.length; i++) {
+                    videoTrack.language = validLanguageTags[i];
+                    testExpected(&quot;videoTrack.language&quot;, validLanguageTags[i]);
+                    textTrack.setAttribute(&quot;srclang&quot;, validLanguageTags[i]);
+                    testExpected(&quot;textTrack.track.language&quot;, validLanguageTags[i]);
+                    audioTrack.language = validLanguageTags[i];
+                    testExpected(&quot;audioTrack.language&quot;, validLanguageTags[i]);
+                }
+                var notOverwritten = &quot;not-overwritten&quot;;
+                for (var i = 0; i &lt; invalidLanguageTags.length; i++) {
+                    // These are accepted in the web page layer but will produce console warnings
+                    videoTrack.language = invalidLanguageTags[i];
+                    testExpected(&quot;videoTrack.language&quot;, invalidLanguageTags[i]);
+                    textTrack.setAttribute(&quot;srclang&quot;, invalidLanguageTags[i]);
+                    testExpected(&quot;textTrack.track.language&quot;, invalidLanguageTags[i]);
+                    audioTrack.language = invalidLanguageTags[i];
+                    testExpected(&quot;audioTrack.language&quot;, invalidLanguageTags[i]);
+                }
+                endTest();
+            }
+
+            function runTest()
+            {
+                findMediaElement();
+
+                loader = new MediaSourceLoader('content/test-fragmented-manifest.json');
+                loader.onload = mediaDataLoaded;
+                loader.onerror = mediaDataLoadingFailed;
+            }
+        &lt;/script&gt;
+    &lt;/head&gt;
+
+    &lt;body onload=&quot;runTest()&quot;&gt;
+        &lt;p&gt;Test that only BCP47 language tags are accepted as valid but still reflected.&lt;/p&gt;
+        &lt;video controls&gt;
+            &lt;track id=&quot;textTrack&quot; kind=&quot;captions&quot; src=&quot;../track/captions-webvtt/captions-fast.vtt&quot; /&gt;
+        &lt;/video&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsmediatrackw3cinterfacesHTMLTrackElementsrclangexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/media/track/w3c/interfaces/HTMLTrackElement/srclang-expected.txt (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/track/w3c/interfaces/HTMLTrackElement/srclang-expected.txt        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/LayoutTests/media/track/w3c/interfaces/HTMLTrackElement/srclang-expected.txt        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -1,3 +1,9 @@
</span><ins>+CONSOLE MESSAGE: line 43: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 64: The language ' foo 
+' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language ' foo 
+' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language contains a null character and is not a valid BCP 47 language tag.
</ins><span class="cx"> 
</span><span class="cx"> PASS HTMLTrackElement.srclang missing value 
</span><span class="cx"> PASS HTMLTrackElement.srclang empty string content attribute 
</span></span></pre></div>
<a id="trunkLayoutTestsmediatrackw3cinterfacesTextTracklanguageexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/media/track/w3c/interfaces/TextTrack/language-expected.txt (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/track/w3c/interfaces/TextTrack/language-expected.txt        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/LayoutTests/media/track/w3c/interfaces/TextTrack/language-expected.txt        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -1,3 +1,5 @@
</span><ins>+CONSOLE MESSAGE: line 1380: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 26: The language contains a null character and is not a valid BCP 47 language tag.
</ins><span class="cx"> 
</span><span class="cx"> PASS TextTrack.language 
</span><span class="cx"> PASS TextTrack.language, \u0000 
</span></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorimportedw3cwebplatformtestshtmldomreflectionembeddedexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-simulator/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/LayoutTests/platform/ios-simulator/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -6,6 +6,32 @@
</span><span class="cx"> Blocked access to external URL http://site.example/path???@#l
</span><span class="cx"> Blocked access to external URL http://site.example/
</span><span class="cx"> Blocked access to external URL http://site.example/path???@#l
</span><ins>+CONSOLE MESSAGE: line 707: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'undefined' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language '7' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language '1.5' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'true' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'false' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language '[object Object]' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language '-Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'null' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'test-toString' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'test-valueOf' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'undefined' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language '7' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language '1.5' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'true' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'false' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language '[object Object]' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language '-Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'null' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'test-toString' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'test-valueOf' is not a valid BCP 47 language tag.
</ins><span class="cx"> Implementers looking to fix bugs might want to use the original version of this suite's test framework, which conveniently aggregates similar errors and only reports failures. This file is (part of) the authoritative conformance test suite, and is suitable for incorporation into automated test suites.
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorwk2importedw3cwebplatformtestshtmldomreflectionembeddedexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -6,6 +6,32 @@
</span><span class="cx"> Blocked access to external URL http://site.example/path???@#l
</span><span class="cx"> Blocked access to external URL http://site.example/
</span><span class="cx"> Blocked access to external URL http://site.example/path???@#l
</span><ins>+CONSOLE MESSAGE: line 707: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'undefined' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language '7' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language '1.5' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'true' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'false' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language '[object Object]' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language '-Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'null' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'test-toString' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 707: The language 'test-valueOf' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'undefined' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language '7' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language '1.5' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'true' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'false' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language '[object Object]' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language '-Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'null' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'test-toString' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 1380: The language 'test-valueOf' is not a valid BCP 47 language tag.
</ins><span class="cx"> Implementers looking to fix bugs might want to use the original version of this suite's test framework, which conveniently aggregates similar errors and only reports failures. This file is (part of) the authoritative conformance test suite, and is suitable for incorporation into automated test suites.
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/Source/WebCore/ChangeLog        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -1,3 +1,52 @@
</span><ins>+2017-01-04  John Wilander  &lt;wilander@apple.com&gt;
+
+        Validate the BCP47-ness of the language string passed to TrackBase::setLanguage()
+        https://bugs.webkit.org/show_bug.cgi?id=123926
+
+        Reviewed by Jer Noble.
+
+        Test: media/media-source/only-bcp47-language-tags-accepted-as-valid.html
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::configureTextTrackGroup):
+            Log message now includes the valid BCP 47 language too.
+        (WebCore::HTMLMediaElement::setSelectedTextTrack):
+            Now sets preferred language to the valid BCP 47 language.
+        * html/track/TextTrack.cpp:
+        (WebCore::TextTrack::setLanguage):
+            Removed fixme and aligned comments with new behavior.
+        * html/track/TrackBase.cpp:
+        (WebCore::TrackBase::TrackBase):
+            Initializes m_validBCP47Language with language parameter.
+        (WebCore::isValidBCP47LanguageTag):
+            New convenience function.
+        (WebCore::TrackBase::setLanguage):
+            Sets m_validBCP47Language if the incoming tag is valid.
+            Produces a console warning if the tag is invalid.
+            The member m_language is set to the incoming tag regardless.
+        (WebCore::TrackBase::validBCP47Language):
+            New getter for valid language tag. To be used internally.
+        * html/track/TrackBase.h:
+            New AtomicString member m_validBCP47Language.
+        (WebCore::TrackBase::setLanguage): Deleted.
+        * html/track/VideoTrack.cpp:
+        (WebCore::VideoTrack::setLanguage):
+            Removed fixme and aligned comments with new behavior.
+        * page/CaptionUserPreferences.cpp:
+        (WebCore::trackDisplayName):
+            Now uses the getter for BCP 47 language.
+        (WebCore::CaptionUserPreferences::textTrackLanguageSelectionScore):
+            Now uses the getter for BCP 47 language.
+        * page/CaptionUserPreferencesMediaAF.cpp:
+        (WebCore::buildDisplayStringForTrackBase):
+            Now uses the getter for BCP 47 language.
+        (WebCore::CaptionUserPreferencesMediaAF::textTrackSelectionScore):
+            Now uses the getter for BCP 47 language.
+        (WebCore::textTrackCompare):
+            Now uses the getter for BCP 47 language.
+        (WebCore::CaptionUserPreferencesMediaAF::sortedTrackListForMenu):
+            Now uses the getter for BCP 47 language.
+
</ins><span class="cx"> 2017-01-04  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Cross Origin importScripts() scripts lack source URL, causes issues with Inspector showing Resource
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.cpp        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -3774,7 +3774,7 @@
</span><span class="cx">             currentlyEnabledTracks.append(textTrack);
</span><span class="cx"> 
</span><span class="cx">         int trackScore = captionPreferences ? captionPreferences-&gt;textTrackSelectionScore(textTrack.get(), this) : 0;
</span><del>-        LOG(Media, &quot;HTMLMediaElement::configureTextTrackGroup(%p) -  '%s' track with language '%s' has score %i&quot;, this, textTrack-&gt;kindKeyword().string().utf8().data(), textTrack-&gt;language().string().utf8().data(), trackScore);
</del><ins>+        LOG(Media, &quot;HTMLMediaElement::configureTextTrackGroup(%p) -  '%s' track with language '%s' and BCP 47 language '%s' has score %d&quot;, this, textTrack-&gt;kindKeyword().string().utf8().data(), textTrack-&gt;language().string().utf8().data(), textTrack-&gt;validBCP47Language().string().utf8().data(), trackScore);
</ins><span class="cx"> 
</span><span class="cx">         if (trackScore) {
</span><span class="cx"> 
</span><span class="lines">@@ -4005,8 +4005,8 @@
</span><span class="cx">         displayMode = CaptionUserPreferences::Automatic;
</span><span class="cx">     else {
</span><span class="cx">         displayMode = CaptionUserPreferences::AlwaysOn;
</span><del>-        if (trackToSelect-&gt;language().length())
-            captionPreferences.setPreferredLanguage(trackToSelect-&gt;language());
</del><ins>+        if (trackToSelect-&gt;validBCP47Language().length())
+            captionPreferences.setPreferredLanguage(trackToSelect-&gt;validBCP47Language());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     captionPreferences.setCaptionDisplayMode(displayMode);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackTextTrackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/TextTrack.cpp (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/TextTrack.cpp        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/Source/WebCore/html/track/TextTrack.cpp        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -556,7 +556,8 @@
</span><span class="cx">     // 11.1 language, on setting:
</span><span class="cx">     // 1. If the value being assigned to this attribute is not an empty string or a BCP 47 language
</span><span class="cx">     // tag[BCP47], then abort these steps.
</span><del>-    // FIXME(123926): Validate the BCP47-ness of langague.
</del><ins>+    // BCP 47 validation is done in TrackBase::setLanguage() which is
+    // shared between all tracks that support setting language.
</ins><span class="cx"> 
</span><span class="cx">     // 2. Update this attribute to the new value.
</span><span class="cx">     TrackBase::setLanguage(language);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackTrackBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/TrackBase.cpp (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/TrackBase.cpp        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/Source/WebCore/html/track/TrackBase.cpp        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -26,6 +26,9 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;TrackBase.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;Language.h&quot;
+#include &lt;wtf/text/StringBuilder.h&gt;
+
</ins><span class="cx"> #if ENABLE(VIDEO_TRACK)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;HTMLMediaElement.h&quot;
</span><span class="lines">@@ -39,6 +42,7 @@
</span><span class="cx">     , m_id(id)
</span><span class="cx">     , m_label(label)
</span><span class="cx">     , m_language(language)
</span><ins>+    , m_validBCP47Language(language)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(type != BaseTrack);
</span><span class="cx">     m_type = type;
</span><span class="lines">@@ -53,6 +57,83 @@
</span><span class="cx">     return m_mediaElement;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// See: https://tools.ietf.org/html/bcp47#section-2.1
+static bool isValidBCP47LanguageTag(const String&amp; languageTag)
+{
+    auto const length = languageTag.length();
+
+    // Max length picked as double the longest example tag in spec which is 49 characters:
+    // https://tools.ietf.org/html/bcp47#section-4.4.2
+    if (length &lt; 2 || length &gt; 100)
+        return false;
+
+    UChar firstChar = languageTag[0];
+
+    if (!isASCIIAlpha(firstChar))
+        return false;
+
+    UChar secondChar = languageTag[1];
+
+    if (length == 2)
+        return isASCIIAlpha(secondChar);
+
+    bool grandFatheredIrregularOrPrivateUse = (firstChar == 'i' || firstChar == 'x') &amp;&amp; secondChar == '-';
+    unsigned nextCharIndexToCheck;
+
+    if (!grandFatheredIrregularOrPrivateUse) {
+        if (!isASCIIAlpha(secondChar))
+            return false;
+
+        if (length == 3)
+            return isASCIIAlpha(languageTag[2]);
+
+        if (isASCIIAlpha(languageTag[2])) {
+            if (languageTag[3] == '-')
+                nextCharIndexToCheck = 4;
+            else
+                return false;
+        } else if (languageTag[2] == '-')
+            nextCharIndexToCheck = 3;
+        else
+            return false;
+    } else
+        nextCharIndexToCheck = 2;
+
+    for (; nextCharIndexToCheck &lt; length; ++nextCharIndexToCheck) {
+        UChar c = languageTag[nextCharIndexToCheck];
+        if (isASCIIAlphanumeric(c) || c == '-')
+            continue;
+        return false;
+    }
+    return true;
+}
+    
+void TrackBase::setLanguage(const AtomicString&amp; language)
+{
+    if (!language.isEmpty() &amp;&amp; !isValidBCP47LanguageTag(language)) {
+        String message;
+        if (language.contains((UChar)'\0'))
+            message = WTF::ASCIILiteral(&quot;The language contains a null character and is not a valid BCP 47 language tag.&quot;);
+        else {
+            StringBuilder stringBuilder;
+            stringBuilder.appendLiteral(&quot;The language '&quot;);
+            stringBuilder.append(language);
+            stringBuilder.appendLiteral(&quot;' is not a valid BCP 47 language tag.&quot;);
+            message = stringBuilder.toString();
+        }
+        if (auto element = this-&gt;element())
+            element-&gt;document().addConsoleMessage(MessageSource::Rendering, MessageLevel::Warning, message);
+    } else
+        m_validBCP47Language = language;
+    
+    m_language = language;
+}
+
+AtomicString TrackBase::validBCP47Language() const
+{
+    return m_validBCP47Language;
+}
+
</ins><span class="cx"> MediaTrackBase::MediaTrackBase(Type type, const AtomicString&amp; id, const AtomicString&amp; label, const AtomicString&amp; language)
</span><span class="cx">     : TrackBase(type, id, label, language)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackTrackBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/TrackBase.h (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/TrackBase.h        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/Source/WebCore/html/track/TrackBase.h        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -54,8 +54,9 @@
</span><span class="cx">     AtomicString label() const { return m_label; }
</span><span class="cx">     void setLabel(const AtomicString&amp; label) { m_label = label; }
</span><span class="cx"> 
</span><ins>+    AtomicString validBCP47Language() const;
</ins><span class="cx">     AtomicString language() const { return m_language; }
</span><del>-    virtual void setLanguage(const AtomicString&amp; language) { m_language = language; }
</del><ins>+    virtual void setLanguage(const AtomicString&amp;);
</ins><span class="cx"> 
</span><span class="cx">     virtual void clearClient() = 0;
</span><span class="cx"> 
</span><span class="lines">@@ -83,6 +84,7 @@
</span><span class="cx">     AtomicString m_id;
</span><span class="cx">     AtomicString m_label;
</span><span class="cx">     AtomicString m_language;
</span><ins>+    AtomicString m_validBCP47Language;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class MediaTrackBase : public TrackBase {
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackVideoTrackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/VideoTrack.cpp (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/VideoTrack.cpp        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/Source/WebCore/html/track/VideoTrack.cpp        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -205,7 +205,8 @@
</span><span class="cx">     // 10.1 language, on setting:
</span><span class="cx">     // 1. If the value being assigned to this attribute is not an empty string or a BCP 47 language
</span><span class="cx">     // tag[BCP47], then abort these steps.
</span><del>-    // FIXME(123926): Validate the BCP47-ness of langague.
</del><ins>+    // BCP 47 validation is done in TrackBase::setLanguage() which is
+    // shared between all tracks that support setting language.
</ins><span class="cx"> 
</span><span class="cx">     // 2. Update this attribute to the new value.
</span><span class="cx">     MediaTrackBase::setLanguage(language);
</span></span></pre></div>
<a id="trunkSourceWebCorepageCaptionUserPreferencescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/CaptionUserPreferences.cpp (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/CaptionUserPreferences.cpp        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/Source/WebCore/page/CaptionUserPreferences.cpp        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -203,11 +203,11 @@
</span><span class="cx">     if (track == TextTrack::captionMenuAutomaticItem())
</span><span class="cx">         return textTrackAutomaticMenuItemText();
</span><span class="cx"> 
</span><del>-    if (track-&gt;label().isEmpty() &amp;&amp; track-&gt;language().isEmpty())
</del><ins>+    if (track-&gt;label().isEmpty() &amp;&amp; track-&gt;validBCP47Language().isEmpty())
</ins><span class="cx">         return textTrackNoLabelText();
</span><span class="cx">     if (!track-&gt;label().isEmpty())
</span><span class="cx">         return track-&gt;label();
</span><del>-    return track-&gt;language();
</del><ins>+    return track-&gt;validBCP47Language();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String CaptionUserPreferences::displayNameForTrack(TextTrack* track) const
</span><span class="lines">@@ -240,11 +240,11 @@
</span><span class="cx"> 
</span><span class="cx"> static String trackDisplayName(AudioTrack* track)
</span><span class="cx"> {
</span><del>-    if (track-&gt;label().isEmpty() &amp;&amp; track-&gt;language().isEmpty())
</del><ins>+    if (track-&gt;label().isEmpty() &amp;&amp; track-&gt;validBCP47Language().isEmpty())
</ins><span class="cx">         return audioTrackNoLabelText();
</span><span class="cx">     if (!track-&gt;label().isEmpty())
</span><span class="cx">         return track-&gt;label();
</span><del>-    return track-&gt;language();
</del><ins>+    return track-&gt;validBCP47Language();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String CaptionUserPreferences::displayNameForTrack(AudioTrack* track) const
</span><span class="lines">@@ -283,11 +283,11 @@
</span><span class="cx"> 
</span><span class="cx"> int CaptionUserPreferences::textTrackLanguageSelectionScore(TextTrack* track, const Vector&lt;String&gt;&amp; preferredLanguages) const
</span><span class="cx"> {
</span><del>-    if (track-&gt;language().isEmpty())
</del><ins>+    if (track-&gt;validBCP47Language().isEmpty())
</ins><span class="cx">         return 0;
</span><span class="cx"> 
</span><span class="cx">     bool exactMatch;
</span><del>-    size_t languageMatchIndex = indexOfBestMatchingLanguageInList(track-&gt;language(), preferredLanguages, exactMatch);
</del><ins>+    size_t languageMatchIndex = indexOfBestMatchingLanguageInList(track-&gt;validBCP47Language(), preferredLanguages, exactMatch);
</ins><span class="cx">     if (languageMatchIndex &gt;= preferredLanguages.size())
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepageCaptionUserPreferencesMediaAFcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/CaptionUserPreferencesMediaAF.cpp (210279 => 210280)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/CaptionUserPreferencesMediaAF.cpp        2017-01-04 19:20:51 UTC (rev 210279)
+++ trunk/Source/WebCore/page/CaptionUserPreferencesMediaAF.cpp        2017-01-04 19:21:42 UTC (rev 210280)
</span><span class="lines">@@ -614,7 +614,7 @@
</span><span class="cx"> static void buildDisplayStringForTrackBase(StringBuilder&amp; displayName, const TrackBase&amp; track)
</span><span class="cx"> {
</span><span class="cx">     String label = track.label();
</span><del>-    String trackLanguageIdentifier = track.language();
</del><ins>+    String trackLanguageIdentifier = track.validBCP47Language();
</ins><span class="cx"> 
</span><span class="cx">     RetainPtr&lt;CFLocaleRef&gt; currentLocale = adoptCF(CFLocaleCreate(kCFAllocatorDefault, defaultLanguage().createCFString().get()));
</span><span class="cx">     RetainPtr&lt;CFStringRef&gt; localeIdentifier = adoptCF(CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorDefault, trackLanguageIdentifier.createCFString().get()));
</span><span class="lines">@@ -737,7 +737,7 @@
</span><span class="cx">         if (!mediaElement || !mediaElement-&gt;player())
</span><span class="cx">             return 0;
</span><span class="cx"> 
</span><del>-        String textTrackLanguage = track-&gt;language();
</del><ins>+        String textTrackLanguage = track-&gt;validBCP47Language();
</ins><span class="cx">         if (textTrackLanguage.isEmpty())
</span><span class="cx">             return 0;
</span><span class="cx"> 
</span><span class="lines">@@ -804,7 +804,7 @@
</span><span class="cx"> static bool textTrackCompare(const RefPtr&lt;TextTrack&gt;&amp; a, const RefPtr&lt;TextTrack&gt;&amp; b)
</span><span class="cx"> {
</span><span class="cx">     String preferredLanguageDisplayName = displayNameForLanguageLocale(languageIdentifier(defaultLanguage()));
</span><del>-    String aLanguageDisplayName = displayNameForLanguageLocale(languageIdentifier(a-&gt;language()));
</del><ins>+    String aLanguageDisplayName = displayNameForLanguageLocale(languageIdentifier(a-&gt;validBCP47Language()));
</ins><span class="cx">     String bLanguageDisplayName = displayNameForLanguageLocale(languageIdentifier(b-&gt;language()));
</span><span class="cx"> 
</span><span class="cx">     // Tracks in the user's preferred language are always at the top of the menu.
</span><span class="lines">@@ -844,7 +844,7 @@
</span><span class="cx">     
</span><span class="cx">     for (unsigned i = 0, length = trackList-&gt;length(); i &lt; length; ++i) {
</span><span class="cx">         AudioTrack* track = trackList-&gt;item(i);
</span><del>-        String language = displayNameForLanguageLocale(track-&gt;language());
</del><ins>+        String language = displayNameForLanguageLocale(track-&gt;validBCP47Language());
</ins><span class="cx">         tracksForMenu.append(track);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -867,7 +867,7 @@
</span><span class="cx"> 
</span><span class="cx">     for (unsigned i = 0, length = trackList-&gt;length(); i &lt; length; ++i) {
</span><span class="cx">         TextTrack* track = trackList-&gt;item(i);
</span><del>-        String language = displayNameForLanguageLocale(track-&gt;language());
</del><ins>+        String language = displayNameForLanguageLocale(track-&gt;validBCP47Language());
</ins><span class="cx"> 
</span><span class="cx">         if (displayMode == Manual) {
</span><span class="cx">             LOG(Media, &quot;CaptionUserPreferencesMediaAF::sortedTrackListForMenu - adding '%s' track with language '%s' because selection mode is 'manual'&quot;, track-&gt;kindKeyword().string().utf8().data(), language.utf8().data());
</span></span></pre>
</div>
</div>

</body>
</html>