diff options
Diffstat (limited to 'Source/WebCore/html/track/TrackBase.cpp')
-rw-r--r-- | Source/WebCore/html/track/TrackBase.cpp | 109 |
1 files changed, 96 insertions, 13 deletions
diff --git a/Source/WebCore/html/track/TrackBase.cpp b/Source/WebCore/html/track/TrackBase.cpp index e93e9e908..bc95111e1 100644 --- a/Source/WebCore/html/track/TrackBase.cpp +++ b/Source/WebCore/html/track/TrackBase.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -26,20 +26,23 @@ #include "config.h" #include "TrackBase.h" -#include "HTMLMediaElement.h" +#include "Language.h" +#include <wtf/text/StringBuilder.h> #if ENABLE(VIDEO_TRACK) +#include "HTMLMediaElement.h" + namespace WebCore { +static int s_uniqueId = 0; + TrackBase::TrackBase(Type type, const AtomicString& id, const AtomicString& label, const AtomicString& language) - : m_mediaElement(0) -#if ENABLE(MEDIA_SOURCE) - , m_sourceBuffer(0) -#endif + : m_uniqueId(++s_uniqueId) , m_id(id) , m_label(label) , m_language(language) + , m_validBCP47Language(language) { ASSERT(type != BaseTrack); m_type = type; @@ -54,19 +57,99 @@ Element* TrackBase::element() return m_mediaElement; } -void TrackBase::setKind(const AtomicString& kind) +// See: https://tools.ietf.org/html/bcp47#section-2.1 +static bool isValidBCP47LanguageTag(const String& languageTag) { - setKindInternal(kind); + 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 < 2 || length > 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') && 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 < length; ++nextCharIndexToCheck) { + UChar c = languageTag[nextCharIndexToCheck]; + if (isASCIIAlphanumeric(c) || c == '-') + continue; + return false; + } + return true; +} + +void TrackBase::setLanguage(const AtomicString& language) +{ + if (!language.isEmpty() && !isValidBCP47LanguageTag(language)) { + String message; + if (language.contains((UChar)'\0')) + message = WTF::ASCIILiteral("The language contains a null character and is not a valid BCP 47 language tag."); + else { + StringBuilder stringBuilder; + stringBuilder.appendLiteral("The language '"); + stringBuilder.append(language); + stringBuilder.appendLiteral("' is not a valid BCP 47 language tag."); + message = stringBuilder.toString(); + } + if (auto element = this->element()) + element->document().addConsoleMessage(MessageSource::Rendering, MessageLevel::Warning, message); + } else + m_validBCP47Language = language; + + m_language = language; } -void TrackBase::setKindInternal(const AtomicString& kind) +AtomicString TrackBase::validBCP47Language() const { - String oldKind = m_kind; + return m_validBCP47Language; +} +MediaTrackBase::MediaTrackBase(Type type, const AtomicString& id, const AtomicString& label, const AtomicString& language) + : TrackBase(type, id, label, language) +{ +} + +void MediaTrackBase::setKind(const AtomicString& kind) +{ + setKindInternal(kind); +} + +void MediaTrackBase::setKindInternal(const AtomicString& kind) +{ if (isValidKind(kind)) m_kind = kind; else - m_kind = defaultKindKeyword(); + m_kind = emptyAtom; } } // namespace WebCore |