Beispiel #1
0
ContentDispositionType contentDispositionType(const String& contentDisposition)
{
    if (contentDisposition.isEmpty())
        return ContentDispositionNone;

    Vector<String> parameters;
    contentDisposition.split(';', parameters);

    if (parameters.isEmpty())
        return ContentDispositionNone;

    String dispositionType = parameters[0];
    dispositionType.stripWhiteSpace();

    if (equalIgnoringCase(dispositionType, "inline"))
        return ContentDispositionInline;

    // Some broken sites just send bogus headers like
    //
    //   Content-Disposition: ; filename="file"
    //   Content-Disposition: filename="file"
    //   Content-Disposition: name="file"
    //
    // without a disposition token... screen those out.
    if (!isValidHTTPToken(dispositionType))
        return ContentDispositionNone;

    // We have a content-disposition of "attachment" or unknown.
    // RFC 2183, section 2.8 says that an unknown disposition
    // value should be treated as "attachment"
    return ContentDispositionAttachment;  
}
Beispiel #2
0
SMILTime SVGSMILElement::parseClockValue(const String& data)
{
    if (data.isNull())
        return SMILTime::unresolved();

    String parse = data.stripWhiteSpace();

    DEFINE_STATIC_LOCAL(const AtomicString, indefiniteValue, ("indefinite", AtomicString::ConstructFromLiteral));
    if (parse == indefiniteValue)
        return SMILTime::indefinite();

    double result = 0;
    bool ok;
    size_t doublePointOne = parse.find(':');
    size_t doublePointTwo = parse.find(':', doublePointOne + 1);
    if (doublePointOne == 2 && doublePointTwo == 5 && parse.length() >= 8) {
        result += parse.substring(0, 2).toUIntStrict(&ok) * 60 * 60;
        if (!ok)
            return SMILTime::unresolved();
        result += parse.substring(3, 2).toUIntStrict(&ok) * 60;
        if (!ok)
            return SMILTime::unresolved();
        result += parse.substring(6).toDouble(&ok);
    } else if (doublePointOne == 2 && doublePointTwo == notFound && parse.length() >= 5) {
        result += parse.substring(0, 2).toUIntStrict(&ok) * 60;
        if (!ok)
            return SMILTime::unresolved();
        result += parse.substring(3).toDouble(&ok);
    } else
        return parseOffsetValue(parse);

    if (!ok)
        return SMILTime::unresolved();
    return result;
}
bool ScriptElementData::shouldExecuteAsJavaScript() const
{
    /*
         Mozilla 1.8 accepts javascript1.0 - javascript1.7, but WinIE 7 accepts only javascript1.1 - javascript1.3.
         Mozilla 1.8 and WinIE 7 both accept javascript and livescript.
         WinIE 7 accepts ecmascript and jscript, but Mozilla 1.8 doesn't.
         Neither Mozilla 1.8 nor WinIE 7 accept leading or trailing whitespace.
         We want to accept all the values that either of these browsers accept, but not other values.
     */
    String type = m_scriptElement->typeAttributeValue();
    if (!type.isEmpty()) {
        if (!MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace().lower()))
            return false;
    } else {
        String language = m_scriptElement->languageAttributeValue();
        if (!language.isEmpty() && !isSupportedJavaScriptLanguage(language))
            return false;
    }    

    // No type or language is specified, so we assume the script to be JavaScript.
    // We don't yet support setting event listeners via the 'for' attribute for scripts.
    // If there is such an attribute it's likely better to not execute the script than to do so
    // immediately and unconditionally.
    // FIXME: After <rdar://problem/4471751> / https://bugs.webkit.org/show_bug.cgi?id=16915 are resolved 
    // and we support the for syntax in script tags, this check can be removed and we should just
    // return 'true' here.
    String forAttribute = m_scriptElement->forAttributeValue();
    return forAttribute.isEmpty();
}
Beispiel #4
0
static String normalizeType(const String& type)
{
    String cleanType = type.stripWhiteSpace().lower();
    if (cleanType == mimeTypeText || cleanType.startsWith(mimeTypeTextPlainEtc))
        return mimeTypeTextPlain;
    return cleanType;
}
bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& delay, String& url)
{
    unsigned len = refresh.length();
    unsigned pos = 0;

    if (!skipWhiteSpace(refresh, pos, fromHttpEquivMeta))
        return false;

    while (pos != len && refresh[pos] != ',' && refresh[pos] != ';')
        ++pos;

    if (pos == len) { // no URL
        url = String();
        bool ok;
        delay = refresh.stripWhiteSpace().toDouble(&ok);
        return ok;
    } else {
        bool ok;
        delay = refresh.left(pos).stripWhiteSpace().toDouble(&ok);
        if (!ok)
            return false;

        ++pos;
        skipWhiteSpace(refresh, pos, fromHttpEquivMeta);
        unsigned urlStartPos = pos;
        if (refresh.find("url", urlStartPos, TextCaseInsensitive) == urlStartPos) {
            urlStartPos += 3;
            skipWhiteSpace(refresh, urlStartPos, fromHttpEquivMeta);
            if (refresh[urlStartPos] == '=') {
                ++urlStartPos;
                skipWhiteSpace(refresh, urlStartPos, fromHttpEquivMeta);
            } else {
                urlStartPos = pos; // e.g. "Refresh: 0; url.html"
            }
        }

        unsigned urlEndPos = len;

        if (refresh[urlStartPos] == '"' || refresh[urlStartPos] == '\'') {
            UChar quotationMark = refresh[urlStartPos];
            urlStartPos++;
            while (urlEndPos > urlStartPos) {
                urlEndPos--;
                if (refresh[urlEndPos] == quotationMark)
                    break;
            }

            // https://bugs.webkit.org/show_bug.cgi?id=27868
            // Sometimes there is no closing quote for the end of the URL even though there was an opening quote.
            // If we looped over the entire alleged URL string back to the opening quote, just go ahead and use everything
            // after the opening quote instead.
            if (urlEndPos == urlStartPos)
                urlEndPos = len;
        }

        url = refresh.substring(urlStartPos, urlEndPos - urlStartPos).stripWhiteSpace();
        return true;
    }
}
Beispiel #6
0
bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const String& type, const String& typeAttribute) const
{
    if (!directive)
        return true;
    if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
        return false;
    return directive->allows(type);
}
String FetchUtils::normalizeHeaderValue(const String& value)
{
    // https://fetch.spec.whatwg.org/#concept-header-value-normalize
    // Strip leading and trailing whitespace from header value.
    // HTTP whitespace bytes are 0x09, 0x0A, 0x0D, and 0x20.

    return value.stripWhiteSpace(isHTTPWhitespace);
}
Beispiel #8
0
Color SVGColor::colorFromRGBColorString(const String& colorString)
{
    // FIXME: Rework css parser so it is more SVG aware.
    RGBA32 color;
    if (CSSParser::parseColor(color, colorString.stripWhiteSpace()))
        return color;
    return Color();
}
StyleColor CSSParser::colorFromRGBColorString(const String& string)
{
    // FIXME: Rework css parser so it is more SVG aware.
    RGBA32 color;
    if (parseColor(color, string.stripWhiteSpace()))
        return StyleColor(color);
    // FIXME: This branch catches the string currentColor, but we should error if we have an illegal color value.
    return StyleColor::currentColor();
}
Beispiel #10
0
Color SVGColor::colorFromRGBColorString(const String& colorString)
{
    String s = colorString.stripWhiteSpace();
    // FIXME: rework css parser so it is more svg aware
    RGBA32 color;
    if (CSSParser::parseColor(color, s))
        return color;
    return Color();
}
Beispiel #11
0
bool DOMCSSNamespace::supports(const String& property, const String& value)
{
    CSSPropertyID propertyID = cssPropertyID(property.stripWhiteSpace());

    if (propertyID == CSSPropertyInvalid)
        return false;

    // CSSParser::parseValue() won't work correctly if !important is present,
    // so just get rid of it. It doesn't matter to supports() if it's actually
    // there or not, provided how it's specified in the value is correct.
    String normalizedValue = value.stripWhiteSpace().simplifyWhiteSpace();
    normalizedValue = valueWithoutImportant(normalizedValue);

    if (normalizedValue.isEmpty())
        return false;

    auto dummyStyle = MutableStyleProperties::create();
    return CSSParser::parseValue(dummyStyle, propertyID, normalizedValue, false, CSSStrictMode, nullptr) != CSSParser::ParseResult::Error;
}
Beispiel #12
0
bool DOMWindowCSS::supports(const String& property, const String& value) const
{
    CSSPropertyID propertyID = cssPropertyID(property.stripWhiteSpace());
    if (propertyID == CSSPropertyInvalid)
        return false;
    ASSERT(CSSPropertyMetadata::isEnabledProperty(propertyID));

    // CSSParser::parseValue() won't work correctly if !important is present,
    // so just get rid of it. It doesn't matter to supports() if it's actually
    // there or not, provided how it's specified in the value is correct.
    String normalizedValue = value.stripWhiteSpace().simplifyWhiteSpace();
    normalizedValue = valueWithoutImportant(normalizedValue);

    if (normalizedValue.isEmpty())
        return false;

    RefPtrWillBeRawPtr<MutableStylePropertySet> dummyStyle = MutableStylePropertySet::create();
    return CSSParser::parseValue(dummyStyle.get(), propertyID, normalizedValue, false, HTMLStandardMode, 0);
}
bool SVGColor::colorFromRGBColorString(const String& colorString, Color& color)
{
    // FIXME: Rework css parser so it is more SVG aware.
    RGBA32 rgba;
    if (CSSParser::parseColor(rgba, colorString.stripWhiteSpace())) {
        color = rgba;
        return true;
    }
    return false;
}
String Path::debugString() const
{
    String result;

    SkPath::Iter iter(*m_path, false);
    SkPoint pts[4];

    int numPoints = m_path->getPoints(0, 0);
    SkPath::Verb verb;

    do {
        verb = iter.next(pts);
        switch (verb) {
        case SkPath::kMove_Verb:
            result += String::format("M%.2f,%.2f ", pts[0].fX, pts[0].fY);
            numPoints -= 1;
            break;
        case SkPath::kLine_Verb:
          if (!iter.isCloseLine()) {
                result += String::format("L%.2f,%.2f ", pts[1].fX, pts[1].fY); 
                numPoints -= 1;
            }
            break;
        case SkPath::kQuad_Verb:
            result += String::format("Q%.2f,%.2f,%.2f,%.2f ",
                pts[1].fX, pts[1].fY,
                pts[2].fX, pts[2].fY);
            numPoints -= 2;
            break;
        case SkPath::kCubic_Verb:
            result += String::format("C%.2f,%.2f,%.2f,%.2f,%.2f,%.2f ",
                pts[1].fX, pts[1].fY,
                pts[2].fX, pts[2].fY,
                pts[3].fX, pts[3].fY);
            numPoints -= 3;
            break;
        case SkPath::kClose_Verb:
            result += "Z ";
            break;
        case SkPath::kDone_Verb:
            break;
        }
    } while (verb != SkPath::kDone_Verb);

    // If you have a path that ends with an M, Skia will not iterate the
    // trailing M. That's nice of it, but Apple's paths output the trailing M
    // and we want out layout dumps to look like theirs
    if (numPoints) {
        ASSERT(numPoints==1);
        m_path->getLastPt(pts);
        result += String::format("M%.2f,%.2f ", pts[0].fX, pts[0].fY);
    }

    return result.stripWhiteSpace();
}
bool ResourceResponseBase::isAttachment() const
{
    lazyInit();

    String value = m_httpHeaderFields.get("Content-Disposition");
    int loc = value.find(';');
    if (loc != -1)
        value = value.left(loc);
    value = value.stripWhiteSpace();
    return equalIgnoringCase(value, "attachment");
}
Beispiel #16
0
UChar MathMLOperatorElement::parseOperatorText(const String& string)
{
    // We collapse the whitespace and replace the hyphens by minus signs.
    AtomicString textContent = string.stripWhiteSpace().simplifyWhiteSpace().replace(hyphenMinus, minusSign).impl();

    // We verify whether the operator text can be represented by a single UChar.
    // FIXME: This is a really inefficient way to extract a character from a string (https://webkit.org/b/160241#c7).
    // FIXME: This does not handle surrogate pairs (https://webkit.org/b/122296).
    // FIXME: This does not handle <mo> operators with multiple characters (https://webkit.org/b/124828).
    return textContent.length() == 1 ? textContent[0] : 0;
}
Beispiel #17
0
String OptionElement::collectOptionLabelOrText(const OptionElementData& data, const Element* element)
{
    Document& document = element->document();
    String text;
    // WinIE does not use the label attribute, so as a quirk, we ignore it.
    if (document.inQuirksMode())
        text = data.label();
    if (text.isEmpty())
        text = collectOptionInnerText(element);
    return text.stripWhiteSpace().simplifyWhiteSpace();
}
String WMLOptGroupElement::groupLabelText() const
{
    String itemText = document()->displayStringModifiedByEncoding(m_title);

    // In WinIE, leading and trailing whitespace is ignored in options and optgroups. We match this behavior.
    itemText = itemText.stripWhiteSpace();
    // We want to collapse our whitespace too.  This will match other browsers.
    itemText = itemText.simplifyWhiteSpace();

    return itemText;
}
Beispiel #19
0
Color SVGColor::colorFromRGBColorString(const String& colorString)
{
    // FIXME: Rename to parseSVGColor? There's already a parseSVGColor in the CSS parser. How is it different?
    // FIXME: Rework CSS parser so it exactly matches what the SVG specification requires?
    // FIXME: Move this out of the SVGColor class?
    // FIXME: Is it really OK to do stripWhitespace here instead of stripLeadingAndTrailingHTMLSpaces?
    RGBA32 color;
    if (CSSParser::parseColor(color, colorString.stripWhiteSpace()))
        return color;
    return Color();
}
Beispiel #20
0
String OptionElement::normalizeText(const Document* document, const String& src)
{
    String text = document->displayStringModifiedByEncoding(src);

    // In WinIE, leading and trailing whitespace is ignored in options and optgroups. We match this behavior.
    text = text.stripWhiteSpace();

    // We want to collapse our whitespace too.  This will match other browsers.
    text = text.simplifyWhiteSpace();
    return text;
}
Beispiel #21
0
String HTMLOptGroupElement::groupLabelText() const {
  String itemText = getAttribute(labelAttr);

  // In WinIE, leading and trailing whitespace is ignored in options and
  // optgroups. We match this behavior.
  itemText = itemText.stripWhiteSpace();
  // We want to collapse our whitespace too.  This will match other browsers.
  itemText = itemText.simplifyWhiteSpace();

  return itemText;
}
Beispiel #22
0
// We provide the IE clipboard types (URL and Text), and the clipboard types
// specified in the WHATWG Web Applications 1.0 draft see
// http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3
static String normalizeType(const String& type, bool* convertToURL = 0) {
  String cleanType = type.stripWhiteSpace().lower();
  if (cleanType == mimeTypeText || cleanType.startsWith(mimeTypeTextPlainEtc))
    return mimeTypeTextPlain;
  if (cleanType == mimeTypeURL) {
    if (convertToURL)
      *convertToURL = true;
    return mimeTypeTextURIList;
  }
  return cleanType;
}
static ClipboardDataType clipboardTypeFromMIMEType(const String& type)
{
    String cleanType = type.stripWhiteSpace().lower();

    // two special cases for IE compatibility
    if (cleanType == "text" || cleanType == "text/plain" || cleanType.startsWith("text/plain;"))
        return ClipboardDataTypeText;
    if (cleanType == "url" || cleanType == "text/uri-list")
        return ClipboardDataTypeURL;

    return ClipboardDataTypeNone;
}
bool ResourceResponseBase::isAttachment() const
{
    lazyInit(AllFields);

    String value = m_httpHeaderFields.get(HTTPHeaderName::ContentDisposition);
    size_t loc = value.find(';');
    if (loc != notFound)
        value = value.left(loc);
    value = value.stripWhiteSpace();

    return equalIgnoringCase(value, "attachment");
}
static String truncatedStringForLookupMenuItem(const String& original)
{
    if (original.isEmpty())
        return original;

    // Truncate the string if it's too long. This is in consistency with AppKit.
    unsigned maxNumberOfGraphemeClustersInLookupMenuItem = 24;
    DEFINE_STATIC_LOCAL(String, ellipsis, (&horizontalEllipsis, 1));

    String trimmed = original.stripWhiteSpace();
    unsigned numberOfCharacters = numCharactersInGraphemeClusters(trimmed, maxNumberOfGraphemeClustersInLookupMenuItem);
    return numberOfCharacters == trimmed.length() ? trimmed : trimmed.left(numberOfCharacters) + ellipsis;
}
void LayoutMenuList::setTextFromOption(int optionIndex)
{
    HTMLSelectElement* select = selectElement();
    const HeapVector<Member<HTMLElement>>& listItems = select->listItems();
    const int size = listItems.size();

    String text = emptyString();
    m_optionStyle.clear();

    if (selectElement()->multiple()) {
        unsigned selectedCount = 0;
        int firstSelectedIndex = -1;
        for (int i = 0; i < size; ++i) {
            Element* element = listItems[i];
            if (!isHTMLOptionElement(*element))
                continue;

            if (toHTMLOptionElement(element)->selected()) {
                if (++selectedCount == 1)
                    firstSelectedIndex = i;
            }
        }

        if (selectedCount == 1) {
            ASSERT(0 <= firstSelectedIndex);
            ASSERT(firstSelectedIndex < size);
            HTMLOptionElement* selectedOptionElement = toHTMLOptionElement(listItems[firstSelectedIndex]);
            ASSERT(selectedOptionElement->selected());
            text = selectedOptionElement->textIndentedToRespectGroupLabel();
            m_optionStyle = selectedOptionElement->mutableComputedStyle();
        } else {
            Locale& locale = select->locale();
            String localizedNumberString = locale.convertToLocalizedNumber(String::number(selectedCount));
            text = locale.queryString(WebLocalizedString::SelectMenuListText, localizedNumberString);
            ASSERT(!m_optionStyle);
        }
    } else {
        const int i = select->optionToListIndex(optionIndex);
        if (i >= 0 && i < size) {
            Element* element = listItems[i];
            if (isHTMLOptionElement(*element)) {
                text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
                m_optionStyle = element->mutableComputedStyle();
            }
        }
    }

    setText(text.stripWhiteSpace());

    didUpdateActiveOption(optionIndex);
}
Beispiel #27
0
bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& delay, String& url)
{
    int len = refresh.length();
    int pos = 0;
    
    if (!skipWhiteSpace(refresh, pos, fromHttpEquivMeta))
        return false;
    
    while (pos != len && refresh[pos] != ',' && refresh[pos] != ';')
        ++pos;
    
    if (pos == len) { // no URL
        url = String();
        bool ok;
        delay = refresh.stripWhiteSpace().toDouble(&ok);
        return ok;
    } else {
        bool ok;
        delay = refresh.left(pos).stripWhiteSpace().toDouble(&ok);
        if (!ok)
            return false;
        
        ++pos;
        skipWhiteSpace(refresh, pos, fromHttpEquivMeta);
        int urlStartPos = pos;
        if (refresh.find("url", urlStartPos, false) == urlStartPos) {
            urlStartPos += 3;
            skipWhiteSpace(refresh, urlStartPos, fromHttpEquivMeta);
            if (refresh[urlStartPos] == '=') {
                ++urlStartPos;
                skipWhiteSpace(refresh, urlStartPos, fromHttpEquivMeta);
            } else
                urlStartPos = pos;  // e.g. "Refresh: 0; url.html"
        }

        int urlEndPos = len;

        if (refresh[urlStartPos] == '"' || refresh[urlStartPos] == '\'') {
            UChar quotationMark = refresh[urlStartPos];
            urlStartPos++;
            while (urlEndPos > urlStartPos) {
                urlEndPos--;
                if (refresh[urlEndPos] == quotationMark)
                    break;
            }
        }

        url = refresh.substring(urlStartPos, urlEndPos - urlStartPos).stripWhiteSpace();
        return true;
    }
}
Beispiel #28
0
static String findMagicComment(const String& content, const String& name, MagicCommentType commentType, bool* deprecated = 0)
{
    ASSERT(name.find("=") == notFound);
    if (deprecated)
        *deprecated = false;
    String pattern;
    String deprecatedPattern;
    switch (commentType) {
    case JavaScriptMagicComment:
        pattern = "//#[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s\'\"]*)[\040\t]*$";
        deprecatedPattern = "//@[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s\'\"]*)[\040\t]*$";
        break;
    case CSSMagicComment:
        pattern = "/\\*#[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s]*)[\040\t]*\\*/[\040\t]*$";
        deprecatedPattern = "/\\*@[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s]*)[\040\t]*\\*/[\040\t]*$";
        break;
    default:
        ASSERT_NOT_REACHED();
        return String();
    }
    RegularExpression regex(pattern, TextCaseSensitive, MultilineEnabled);
    RegularExpression deprecatedRegex(deprecatedPattern, TextCaseSensitive, MultilineEnabled);

    int matchLength;
    int offset = regex.match(content, 0, &matchLength);
    if (offset == -1) {
        offset = deprecatedRegex.match(content, 0, &matchLength);
        if (offset != -1 && deprecated)
            *deprecated = true;
    }
    if (offset == -1)
        return String();

    String match = content.substring(offset, matchLength);
    size_t separator = match.find("=");
    ASSERT(separator != notFound);
    match = match.substring(separator + 1);

    switch (commentType) {
    case JavaScriptMagicComment:
        return match.stripWhiteSpace();
    case CSSMagicComment: {
        size_t lastStarIndex = match.reverseFind('*');
        ASSERT(lastStarIndex != notFound);
        return match.substring(0, lastStarIndex).stripWhiteSpace();
    }
    default:
        ASSERT_NOT_REACHED();
        return String();
    }
}
MIMEHeader::Encoding MIMEHeader::parseContentTransferEncoding(const String& text)
{
    String encoding = text.stripWhiteSpace().lower();
    if (encoding == "base64")
        return Base64;
    if (encoding == "quoted-printable")
        return QuotedPrintable;
    if (encoding == "7bit")
        return SevenBit;
    if (encoding == "binary")
        return Binary;
    LOG_ERROR("Unknown encoding '%s' found in MIME header.", text.ascii().data());
    return Unknown;
}
void WebContextMenuClient::searchWithGoogle(const Frame* frame)
{
    String searchString = frame->editor()->selectedText();
    searchString.stripWhiteSpace();
    String encoded = encodeWithURLEscapeSequences(searchString);
    encoded.replace("%20", "+");
    
    String url = "http://www.google.com/search?q=" + encoded + "&ie=UTF-8&oe=UTF-8";

    if (Page* page = frame->page()) {
        UserGestureIndicator indicator(DefinitelyProcessingNewUserGesture);
        page->mainFrame()->loader()->urlSelected(KURL(ParsedURLString, url), String(), 0, false, false, MaybeSendReferrer);
    }
}