void FetchHeaderList::append(const String& name, const String& value)
{
    // "To append a name/value (|name|/|value|) pair to a header list (|list|),
    // append a new header whose name is |name|, byte lowercased, and value is
    // |value|, to |list|."
    m_headerList.append(wrapUnique(new Header(name.lower(), value)));
}
Example #2
0
bool CSPSource::schemeMatches(const String& protocol) const {
  DCHECK_EQ(protocol, protocol.lower());
  if (m_scheme == "http")
    return protocol == "http" || protocol == "https";
  if (m_scheme == "ws")
    return protocol == "ws" || protocol == "wss";
  return protocol == m_scheme;
}
PassRefPtr<Attr> Element::getAttributeNode(const String& name)
{
    NamedAttrMap* attrs = attributes(true);
    if (!attrs)
        return 0;
    String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
    return static_pointer_cast<Attr>(attrs->getNamedItem(localName));
}
Example #4
0
TEST(StringTest, ToLowerLocale) {
  CaseFoldingTestData testDataList[] = {
      {
          "Turkic input", turkicInput, turkicLocales,
          sizeof(turkicLocales) / sizeof(const char*),
          "\xC4\xB1sii is\xC4\xB1\xC4\xB1",
      },
      {
          "Turkic input", turkicInput, nonTurkicLocales,
          sizeof(nonTurkicLocales) / sizeof(const char*),
          // U+0130 is lowercased to U+0069 followed by U+0307
          "isii\xCC\x87 i\xCC\x87s\xC4\xB1i",
      },
      {
          "Greek input", greekInput, greekLocales,
          sizeof(greekLocales) / sizeof(const char*),
          "\xCE\xBF\xCE\xB4\xCF\x8C\xCF\x82 \xCE\xBF\xCE\xB4\xCF\x8C\xCF\x82 "
          "\xCF\x83\xCE\xBF \xCF\x83\xCE\xBF \x6F\xCF\x82 \xCE\xBF\xCF\x82 "
          "\xCF\x83 \xE1\xBC\x95\xCE\xBE",
      },
      {
          "Greek input", greekInput, nonGreekLocales,
          sizeof(greekLocales) / sizeof(const char*),
          "\xCE\xBF\xCE\xB4\xCF\x8C\xCF\x82 \xCE\xBF\xCE\xB4\xCF\x8C\xCF\x82 "
          "\xCF\x83\xCE\xBF \xCF\x83\xCE\xBF \x6F\xCF\x82 \xCE\xBF\xCF\x82 "
          "\xCF\x83 \xE1\xBC\x95\xCE\xBE",
      },
      {
          "Lithuanian input", lithuanianInput, lithuanianLocales,
          sizeof(lithuanianLocales) / sizeof(const char*),
          "i \xC3\xAF j j\xCC\x87\xCC\x88 \xC4\xAF \xC4\xAF\xCC\x87\xCC\x88 "
          "i\xCC\x87\xCC\x80 i\xCC\x87\xCC\x81 i\xCC\x87\xCC\x83 "
          "xi\xCC\x87\xCC\x88 xj\xCC\x87\xCC\x88 x\xC4\xAF\xCC\x87\xCC\x88 "
          "xi\xCC\x87\xCC\x80 xi\xCC\x87\xCC\x81 xi\xCC\x87\xCC\x83 xi "
          "x\xC3\xAF xj xj\xCC\x87\xCC\x88 x\xC4\xAF x\xC4\xAF\xCC\x87\xCC\x88",
      },
      {
          "Lithuanian input", lithuanianInput, nonLithuanianLocales,
          sizeof(nonLithuanianLocales) / sizeof(const char*),
          "\x69 \xC3\xAF \x6A \x6A\xCC\x88 \xC4\xAF \xC4\xAF\xCC\x88 \xC3\xAC "
          "\xC3\xAD \xC4\xA9 \x78\x69\xCC\x87\xCC\x88 \x78\x6A\xCC\x87\xCC\x88 "
          "\x78\xC4\xAF\xCC\x87\xCC\x88 \x78\x69\xCC\x87\xCC\x80 "
          "\x78\x69\xCC\x87\xCC\x81 \x78\x69\xCC\x87\xCC\x83 \x78\x69 "
          "\x78\xC3\xAF \x78\x6A \x78\x6A\xCC\x88 \x78\xC4\xAF "
          "\x78\xC4\xAF\xCC\x88",
      },
  };

  for (size_t i = 0; i < sizeof(testDataList) / sizeof(testDataList[0]); ++i) {
    const char* expected = testDataList[i].expected;
    String source = String::fromUTF8(testDataList[i].source);
    for (size_t j = 0; j < testDataList[i].localeListLength; ++j) {
      const char* locale = testDataList[i].localeList[j];
      EXPECT_STREQ(expected, source.lower(locale).utf8().data())
          << testDataList[i].sourceDescription << "; locale=" << locale;
    }
  }
}
void FetchHeaderList::getAll(const String& name, Vector<String>& result) const
{
    const String lowercasedName = name.lower();
    result.clear();
    for (size_t i = 0; i < m_headerList.size(); ++i) {
        if (m_headerList[i]->first == lowercasedName)
            result.append(m_headerList[i]->second);
    }
}
Example #6
0
bool DumpRenderTree::isHTTPTest(const String& test)
{
    if (test.length() < strlen(httpTestSyntax))
        return false;
    String testLower = test.lower();
    int lenHttpTestSyntax = strlen(httpTestSyntax);
    return testLower.substring(0, lenHttpTestSyntax) == httpTestSyntax
        && testLower.substring(lenHttpTestSyntax, strlen(localTestSyntax)) != localTestSyntax;
}
bool FetchHeaderList::has(const String& name) const
{
    const String lowercasedName = name.lower();
    for (size_t i = 0; i < m_headerList.size(); ++i) {
        if (m_headerList[i]->first == lowercasedName)
            return true;
    }
    return false;
}
Example #8
0
PassRefPtr<Element> HTMLDocument::createElement(const String &name, ExceptionCode& ec)
{
    String lowerName(name.lower());
    if (!isValidName(lowerName)) {
        ec = INVALID_CHARACTER_ERR;
        return 0;
    }
    return HTMLElementFactory::createHTMLElement(AtomicString(lowerName), this, 0, false);
}
PassRefPtr<Node> NamedAttrMap::getNamedItem(const String& name) const
{
    String localName = inHTMLDocument(element) ? name.lower() : name;
    Attribute* a = getAttributeItem(localName);
    if (!a)
        return 0;
    
    return a->createAttrIfNeeded(element);
}
OriginAccessEntry::OriginAccessEntry(const String& protocol, const String& host, SubdomainSetting subdomainSetting, IPAddressSetting ipAddressSetting)
    : m_protocol(protocol.lower())
    , m_host(host.lower())
    , m_subdomainSettings(subdomainSetting)
    , m_ipAddressSettings(ipAddressSetting)
    , m_hostIsPublicSuffix(false)
{
    ASSERT(subdomainSetting == AllowSubdomains || subdomainSetting == DisallowSubdomains);

    m_hostIsIPAddress = HostIsIPAddress(host);

    // Look for top-level domains, either with or without an additional dot.
    if (!m_hostIsIPAddress) {
        WebPublicSuffixList* suffixList = Platform::current()->publicSuffixList();
        if (suffixList && m_host.length() <= suffixList->getPublicSuffixLength(m_host) + 1)
            m_hostIsPublicSuffix = true;
    }
}
Example #11
0
unsigned HTTPRequest::parse(const Str & data)
{
	if(!requestLine.length){
		size_t pos;
		if(!data.findFirst(pos, "\r\n"))
			return 0;
		requestLine <<= data.read(0, pos);
		auto result = requestLine.regexpMatches("\\([^ ]*\\) \\([^ ]*\\) HTTP/\\(.*\\)$");
		if(result.size() != 3)
			throw HttpProtocolError("Invalid HTTP request line: %", requestLine);
		method <<= result[0];
		uri <<= result[1];
		version <<= result[2];
	}

	if(!headers.value.length){
		size_t pos;
		if(!data.findFirst(pos, "\r\n\r\n", requestLine.length+2))
			return 0;
		headers.value <<= data.read(requestLine.length+2, pos);
		Array<Str> array = headers.value.split("\r\n");
		String key;
		for(auto & str : array){
			if(str.findFirst(pos, ":")){
				key <<= str.read(0, pos);
				pos++;
				key.trim(" \t");
				key.lower();
			} else {
				if(!key.length)
					throw HttpProtocolError(
						"Invalid header line: %", str);
				pos = 0;
			}
			Str value(str.c_str() + pos, str.length - pos);
			if(!value.startsWith(" ") && !value.startsWith("\t"))
				throw HttpProtocolError(
						"Invalid multiline header "
						"line: %", str);
			value.trim(" \t");
			headers[key].value << value;
		}
	}

	if(!body.length){
		size_t readIn = requestLine.length+2 + headers.value.length+4;
		size_t bodyLength = 0;
		bodyLength <<= headers["content-length"];
		if(data.length < readIn + bodyLength)
			return 0;
		body <<= data.read(readIn, readIn + bodyLength);
		return readIn + bodyLength;
	}

	return 0;
}
Example #12
0
String ImageEncoderUtils::toEncodingMimeType(const String& mimeType,
        const EncodeReason encodeReason) {
    String lowercaseMimeType = mimeType.lower();

    if (mimeType.isNull())
        lowercaseMimeType = DefaultMimeType;

    RequestedImageMimeType imageFormat;
    if (lowercaseMimeType == "image/png") {
        imageFormat = RequestedImageMimeTypePng;
    } else if (lowercaseMimeType == "image/jpeg") {
        imageFormat = RequestedImageMimeTypeJpeg;
    } else if (lowercaseMimeType == "image/webp") {
        imageFormat = RequestedImageMimeTypeWebp;
    } else if (lowercaseMimeType == "image/gif") {
        imageFormat = RequestedImageMimeTypeGif;
    } else if (lowercaseMimeType == "image/bmp" ||
               lowercaseMimeType == "image/x-windows-bmp") {
        imageFormat = RequestedImageMimeTypeBmp;
    } else if (lowercaseMimeType == "image/x-icon") {
        imageFormat = RequestedImageMimeTypeIco;
    } else if (lowercaseMimeType == "image/tiff" ||
               lowercaseMimeType == "image/x-tiff") {
        imageFormat = RequestedImageMimeTypeTiff;
    } else {
        imageFormat = RequestedImageMimeTypeUnknown;
    }

    if (encodeReason == EncodeReasonToDataURL) {
        DEFINE_THREAD_SAFE_STATIC_LOCAL(
            EnumerationHistogram, toDataURLImageFormatHistogram,
            new EnumerationHistogram("Canvas.RequestedImageMimeTypes_toDataURL",
                                     NumberOfRequestedImageMimeTypes));
        toDataURLImageFormatHistogram.count(imageFormat);
    } else if (encodeReason == EncodeReasonToBlobCallback) {
        DEFINE_THREAD_SAFE_STATIC_LOCAL(
            EnumerationHistogram, toBlobCallbackImageFormatHistogram,
            new EnumerationHistogram(
                "Canvas.RequestedImageMimeTypes_toBlobCallback",
                NumberOfRequestedImageMimeTypes));
        toBlobCallbackImageFormatHistogram.count(imageFormat);
    } else if (encodeReason == EncodeReasonConvertToBlobPromise) {
        DEFINE_THREAD_SAFE_STATIC_LOCAL(
            EnumerationHistogram, convertToBlobPromiseImageFormatHistogram,
            new EnumerationHistogram(
                "Canvas.RequestedImageMimeTypes_convertToBlobPromise",
                NumberOfRequestedImageMimeTypes));
        convertToBlobPromiseImageFormatHistogram.count(imageFormat);
    }

    // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this
    // method to be used on a worker thread).
    if (!MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(lowercaseMimeType))
        lowercaseMimeType = DefaultMimeType;
    return lowercaseMimeType;
}
Example #13
0
void WebContext::unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(const String& urlScheme)
{
    if (!urlScheme)
        return;

    String schemeLower = urlScheme.lower();
    globalURLSchemesWithCustomProtocolHandlers().remove(schemeLower);
    for (auto* context : allContexts())
        context->unregisterSchemeForCustomProtocol(schemeLower);
}
void Element::removeAttribute(const String& name, ExceptionCode& ec)
{
    String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;

    if (namedAttrMap) {
        namedAttrMap->removeNamedItem(localName, ec);
        if (ec == NOT_FOUND_ERR)
            ec = 0;
    }
}
Example #15
0
String HTMLCanvasElement::toEncodingMimeType(const String& mimeType)
{
    String lowercaseMimeType = mimeType.lower();

    // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread).
    if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(lowercaseMimeType))
        lowercaseMimeType = "image/png";

    return lowercaseMimeType;
}
OriginAccessEntry::OriginAccessEntry(const String& protocol, const String& host, SubdomainSetting subdomainSetting, IPAddressSetting ipAddressSetting)
    : m_protocol(protocol.lower())
    , m_host(host.lower())
    , m_subdomainSettings(subdomainSetting)
    , m_ipAddressSettings(ipAddressSetting)
    , m_hostIsPublicSuffix(false)
{
    ASSERT(subdomainSetting == AllowSubdomains || subdomainSetting == DisallowSubdomains);

    // Assume that any host that ends with a digit is trying to be an IP address.
    m_hostIsIPAddress = !m_host.isEmpty() && isASCIIDigit(m_host[m_host.length() - 1]);

    // Look for top-level domains, either with or without an additional dot.
    if (!m_hostIsIPAddress) {
        blink::WebPublicSuffixList* suffixList = blink::Platform::current()->publicSuffixList();
        if (suffixList && m_host.length() <= suffixList->getPublicSuffixLength(m_host) + 1)
            m_hostIsPublicSuffix = true;
    }
}
Example #17
0
void ResourceResponseBase::parseCacheControlDirectives() const
{
    ASSERT(!m_haveParsedCacheControlHeader);

    lazyInit(CommonFieldsOnly);

    m_haveParsedCacheControlHeader = true;

    m_cacheControlContainsMustRevalidate = false;
    m_cacheControlContainsNoCache = false;
    m_cacheControlMaxAge = numeric_limits<double>::quiet_NaN();

    DEFINE_STATIC_LOCAL(const AtomicString, cacheControlString, ("cache-control", AtomicString::ConstructFromLiteral));
    DEFINE_STATIC_LOCAL(const AtomicString, noCacheDirective, ("no-cache", AtomicString::ConstructFromLiteral));
    DEFINE_STATIC_LOCAL(const AtomicString, noStoreDirective, ("no-store", AtomicString::ConstructFromLiteral));
    DEFINE_STATIC_LOCAL(const AtomicString, mustRevalidateDirective, ("must-revalidate", AtomicString::ConstructFromLiteral));
    DEFINE_STATIC_LOCAL(const AtomicString, maxAgeDirective, ("max-age", AtomicString::ConstructFromLiteral));

    String cacheControlValue = m_httpHeaderFields.get(cacheControlString);
    if (!cacheControlValue.isEmpty()) {
        Vector<pair<String, String> > directives;
        parseCacheHeader(cacheControlValue, directives);

        size_t directivesSize = directives.size();
        for (size_t i = 0; i < directivesSize; ++i) {
            // RFC2616 14.9.1: A no-cache directive with a value is only meaningful for proxy caches.
            // It should be ignored by a browser level cache.
            if (equalIgnoringCase(directives[i].first, noCacheDirective) && directives[i].second.isEmpty())
                m_cacheControlContainsNoCache = true;
            else if (equalIgnoringCase(directives[i].first, noStoreDirective))
                m_cacheControlContainsNoStore = true;
            else if (equalIgnoringCase(directives[i].first, mustRevalidateDirective))
                m_cacheControlContainsMustRevalidate = true;
            else if (equalIgnoringCase(directives[i].first, maxAgeDirective)) {
                if (!std::isnan(m_cacheControlMaxAge)) {
                    // First max-age directive wins if there are multiple ones.
                    continue;
                }
                bool ok;
                double maxAge = directives[i].second.toDouble(&ok);
                if (ok)
                    m_cacheControlMaxAge = maxAge;
            }
        }
    }

    if (!m_cacheControlContainsNoCache) {
        // Handle Pragma: no-cache
        // This is deprecated and equivalent to Cache-control: no-cache
        // Don't bother tokenizing the value, it is not important
        DEFINE_STATIC_LOCAL(const AtomicString, pragmaHeader, ("pragma", AtomicString::ConstructFromLiteral));
        String pragmaValue = m_httpHeaderFields.get(pragmaHeader);

        m_cacheControlContainsNoCache = pragmaValue.lower().contains(noCacheDirective);
    }
bool Element::hasAttribute(const String& name) const
{
    NamedAttrMap* attrs = attributes(true);
    if (!attrs)
        return false;

    // This call to String::lower() seems to be required but
    // there may be a way to remove it.
    String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
    return attrs->getAttributeItem(localName, false);
}
bool FetchHeaderList::get(const String& name, String& result) const
{
    const String lowercasedName = name.lower();
    for (size_t i = 0; i < m_headerList.size(); ++i) {
        if (m_headerList[i]->first == lowercasedName) {
            result = m_headerList[i]->second;
            return true;
        }
    }
    return false;
}
Example #20
0
void PluginPackage::setMIMEDescription(const String& mimeDescription)
{
    m_fullMIMEDescription = mimeDescription.lower();

    Vector<String> types;
    mimeDescription.lower().split(UChar(';'), false, types);
    for (unsigned i = 0; i < types.size(); ++i) {
        Vector<String> mime;
        types[i].split(UChar(':'), true, mime);
        if (mime.size() > 0) {
            Vector<String> exts;
            if (mime.size() > 1)
                mime[1].split(UChar(','), false, exts);
            determineQuirks(mime[0]);
            m_mimeToExtensions.add(mime[0], exts);
            if (mime.size() > 2)
                m_mimeToDescriptions.add(mime[0], mime[2]);
        }
    }
}
PassRefPtr<Node> NamedAttrMap::removeNamedItem(const String& name, ExceptionCode& ec)
{
    String localName = inHTMLDocument(element) ? name.lower() : name;
    Attribute* a = getAttributeItem(localName);
    if (!a) {
        ec = NOT_FOUND_ERR;
        return 0;
    }
    
    return removeNamedItem(a->name(), ec);
}
Example #22
0
bool SelectionController::modify(const String &alterString, const String &directionString, const String &granularityString)
{
    String alterStringLower = alterString.lower();
    EAlter alter;
    if (alterStringLower == "extend")
        alter = EXTEND;
    else if (alterStringLower == "move")
        alter = MOVE;
    else 
        return false;
    
    String directionStringLower = directionString.lower();
    EDirection direction;
    if (directionStringLower == "forward")
        direction = FORWARD;
    else if (directionStringLower == "backward")
        direction = BACKWARD;
    else if (directionStringLower == "left")
        direction = LEFT;
    else if (directionStringLower == "right")
        direction = RIGHT;
    else
        return false;
        
    String granularityStringLower = granularityString.lower();
    TextGranularity granularity;
    if (granularityStringLower == "character")
        granularity = CharacterGranularity;
    else if (granularityStringLower == "word")
        granularity = WordGranularity;
    else if (granularityStringLower == "sentence")
        granularity = SentenceGranularity;
    else if (granularityStringLower == "line")
        granularity = LineGranularity;
    else if (granularityStringLower == "paragraph")
        granularity = ParagraphGranularity;
    else
        return false;
                
    return modify(alter, direction, granularity);
}
Example #23
0
String MIMETypeRegistry::getMIMETypeForExtension(const String &ext)
{
    String s = ext.lower();
    const ExtensionMap *e = extensionMap;
    while (e->extension) {
        if (s == e->extension)
            return e->mimeType;
        ++e;
    }

    return String();
}
void FetchHeaderList::remove(const String& name)
{
    // "To delete a name (|name|) from a header list (|list|), remove all headers
    // whose name is |name|, byte lowercased, from |list|."
    const String lowercasedName = name.lower();
    for (size_t i = 0; i < m_headerList.size(); ) {
        if (m_headerList[i]->first == lowercasedName)
            m_headerList.remove(i);
        else
            ++i;
    }
}
Example #25
0
void HTMLObjectElement::parseMappedAttribute(MappedAttribute *attr)
{
    String val = attr->value();
    int pos;
    if (attr->name() == typeAttr) {
        m_serviceType = val.lower();
        pos = m_serviceType.find(";");
        if (pos != -1)
          m_serviceType = m_serviceType.left(pos);
        if (renderer())
          m_needWidgetUpdate = true;
        if (!isImageType() && m_imageLoader) {
          delete m_imageLoader;
          m_imageLoader = 0;
        }
    } else if (attr->name() == dataAttr) {
        m_url = parseURL(val);
        if (renderer())
          m_needWidgetUpdate = true;
        if (renderer() && isImageType()) {
          if (!m_imageLoader)
              m_imageLoader = new HTMLImageLoader(this);
          m_imageLoader->updateFromElement();
        }
    } else if (attr->name() == classidAttr) {
        m_classId = val;
        if (renderer())
          m_needWidgetUpdate = true;
    } else if (attr->name() == onloadAttr) {
        setHTMLEventListener(loadEvent, attr);
    } else if (attr->name() == onunloadAttr) {
        setHTMLEventListener(unloadEvent, attr);
    } else if (attr->name() == nameAttr) {
            String newNameAttr = attr->value();
            if (isDocNamedItem() && inDocument() && document()->isHTMLDocument()) {
                HTMLDocument *doc = static_cast<HTMLDocument *>(document());
                doc->removeNamedItem(oldNameAttr);
                doc->addNamedItem(newNameAttr);
            }
            oldNameAttr = newNameAttr;
    } else if (attr->name() == idAttr) {
        String newIdAttr = attr->value();
        if (isDocNamedItem() && inDocument() && document()->isHTMLDocument()) {
            HTMLDocument* doc = static_cast<HTMLDocument*>(document());
            doc->removeDocExtraNamedItem(oldIdAttr);
            doc->addDocExtraNamedItem(newIdAttr);
        }
        oldIdAttr = newIdAttr;
        // also call superclass
        HTMLPlugInElement::parseMappedAttribute(attr);
    } else
        HTMLPlugInElement::parseMappedAttribute(attr);
}
Example #26
0
String MIMETypeRegistry::getMIMETypeForExtension(const String &ext)
{
    String s = ext.lower();
    const ExtensionMap *e = extensionMap;
    while (e->extension) {
        if (s == e->extension)
            return e->mimeType;
        ++e;
    }
    // unknown, let's just assume plain text
    return "text/plain";
}
String FetchHeaderList::extractMIMEType() const
{
    // To extract a MIME type from a header list (headers), run these steps:
    // 1. Let MIMEType be the result of parsing `Content-Type` in headers.
    String mimeType;
    if (!get("Content-Type", mimeType)) {
        // 2. If MIMEType is null or failure, return the empty byte sequence.
        return String();
    }
    // 3. Return MIMEType, byte lowercased.
    return mimeType.lower();
}
String MIMETypeRegistry::getMIMETypeForExtension(const String &ext)
{
    String s = ext.lower();
    const ExtensionMap *e = extensionMap;
    while (e->extension) {
        if (s == e->extension)
            return e->mimeType;
        ++e;
    }

    return "application/octet-stream";
}
Example #29
0
static bool pluginSupportsExtension(PluginData* pluginData, const String& extension)
{
    ASSERT(extension.lower() == extension);

    for (size_t i = 0; i < pluginData->mimes().size(); ++i) {
        const MimeClassInfo& mimeClassInfo = pluginData->mimes()[i];

        if (mimeClassInfo.extensions.contains(extension))
            return true;
    }
    return false;
}
void ScriptLoader::logScriptMimetype(ScriptResource* resource, LocalFrame* frame, String mimetype)
{
    String lowerMimetype = mimetype.lower();
    bool text = lowerMimetype.startsWith("text/");
    bool application = lowerMimetype.startsWith("application/");
    bool expectedJs = MIMETypeRegistry::isSupportedJavaScriptMIMEType(lowerMimetype) || (text && isLegacySupportedJavaScriptLanguage(lowerMimetype.substring(5)));
    bool sameOrigin = m_element->document().getSecurityOrigin()->canRequest(m_resource->url());
    if (expectedJs) {
        return;
    }
    UseCounter::Feature feature = sameOrigin ? (text ? UseCounter::SameOriginTextScript : application ? UseCounter::SameOriginApplicationScript : UseCounter::SameOriginOtherScript) : (text ? UseCounter::CrossOriginTextScript : application ? UseCounter::CrossOriginApplicationScript : UseCounter::CrossOriginOtherScript);
    UseCounter::count(frame, feature);
}