Пример #1
0
// https://tools.ietf.org/html/rfc6455#section-4.1
// "The HTTP version MUST be at least 1.1."
static inline bool headerHasValidHTTPVersion(StringView httpStatusLine)
{
    const char* httpVersionStaticPreambleLiteral = "HTTP/";
    StringView httpVersionStaticPreamble(reinterpret_cast<const LChar*>(httpVersionStaticPreambleLiteral), strlen(httpVersionStaticPreambleLiteral));
    if (!httpStatusLine.startsWith(httpVersionStaticPreamble))
        return false;

    // Check that there is a version number which should be at least three characters after "HTTP/"
    unsigned preambleLength = httpVersionStaticPreamble.length();
    if (httpStatusLine.length() < preambleLength + 3)
        return false;

    auto dotPosition = httpStatusLine.find('.', preambleLength);
    if (dotPosition == notFound)
        return false;

    StringView majorVersionView = httpStatusLine.substring(preambleLength, dotPosition - preambleLength);
    bool isValid;
    int majorVersion = majorVersionView.toIntStrict(isValid);
    if (!isValid)
        return false;

    unsigned minorVersionLength;
    unsigned charactersLeftAfterDotPosition = httpStatusLine.length() - dotPosition;
    for (minorVersionLength = 1; minorVersionLength < charactersLeftAfterDotPosition; minorVersionLength++) {
        if (!isASCIIDigit(httpStatusLine[dotPosition + minorVersionLength]))
            break;
    }
    int minorVersion = (httpStatusLine.substring(dotPosition + 1, minorVersionLength)).toIntStrict(isValid);
    if (!isValid)
        return false;

    return (majorVersion >= 1 && minorVersion >= 1) || majorVersion >= 2;
}
Пример #2
0
static void findGrammaticalErrors(TextCheckerClient& client, StringView text, Vector<TextCheckingResult>& results)
{
    for (unsigned checkLocation = 0; checkLocation < text.length(); ) {
        int badGrammarLocation = -1;
        int badGrammarLength = 0;
        Vector<GrammarDetail> badGrammarDetails;
        client.checkGrammarOfString(text.substring(checkLocation), badGrammarDetails, &badGrammarLocation, &badGrammarLength);
        if (!badGrammarLength)
            break;

        ASSERT(badGrammarLocation >= 0);
        ASSERT(static_cast<unsigned>(badGrammarLocation) <= text.length() - checkLocation);
        ASSERT(badGrammarLength > 0);
        ASSERT(static_cast<unsigned>(badGrammarLength) <= text.length() - checkLocation - badGrammarLocation);

        TextCheckingResult badGrammar;
        badGrammar.type = TextCheckingTypeGrammar;
        badGrammar.location = checkLocation + badGrammarLocation;
        badGrammar.length = badGrammarLength;
        badGrammar.details = std::move(badGrammarDetails);
        results.append(badGrammar);

        checkLocation += badGrammarLocation + badGrammarLength;
    }
}
Пример #3
0
static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset)
{
    ErrorInstance::SourceAppender appender = exception->sourceAppender();
    exception->clearSourceAppender();
    RuntimeType type = exception->runtimeTypeForCause();
    exception->clearRuntimeTypeForCause();

    if (!callFrame->codeBlock()->hasExpressionInfo())
        return;
    
    int startOffset = 0;
    int endOffset = 0;
    int divotPoint = 0;
    unsigned line = 0;
    unsigned column = 0;

    CodeBlock* codeBlock;
    CodeOrigin codeOrigin = callFrame->codeOrigin();
    if (codeOrigin && codeOrigin.inlineCallFrame)
        codeBlock = baselineCodeBlockForInlineCallFrame(codeOrigin.inlineCallFrame);
    else
        codeBlock = callFrame->codeBlock();

    codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset, line, column);
    
    int expressionStart = divotPoint - startOffset;
    int expressionStop = divotPoint + endOffset;

    StringView sourceString = codeBlock->source()->source();
    if (!expressionStop || expressionStart > static_cast<int>(sourceString.length()))
        return;
    
    VM* vm = &callFrame->vm();
    JSValue jsMessage = exception->getDirect(*vm, vm->propertyNames->message);
    if (!jsMessage || !jsMessage.isString())
        return;
    
    String message = asString(jsMessage)->value(callFrame);
    if (expressionStart < expressionStop)
        message = appender(message, codeBlock->source()->getRange(expressionStart, expressionStop).toString(), type, ErrorInstance::FoundExactSource);
    else {
        // No range information, so give a few characters of context.
        int dataLength = sourceString.length();
        int start = expressionStart;
        int stop = expressionStart;
        // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
        // Then strip whitespace.
        while (start > 0 && (expressionStart - start < 20) && sourceString[start - 1] != '\n')
            start--;
        while (start < (expressionStart - 1) && isStrWhiteSpace(sourceString[start]))
            start++;
        while (stop < dataLength && (stop - expressionStart < 20) && sourceString[stop] != '\n')
            stop++;
        while (stop > expressionStart && isStrWhiteSpace(sourceString[stop - 1]))
            stop--;
        message = appender(message, codeBlock->source()->getRange(start, stop).toString(), type, ErrorInstance::FoundApproximateSource);
    }
    exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message));

}
Пример #4
0
TextRun InlineTextBox::constructTextRun(
    const ComputedStyle& style,
    StringView string,
    int maximumLength,
    StringBuilder* charactersWithHyphen) const {
  if (charactersWithHyphen) {
    const AtomicString& hyphenString = style.hyphenString();
    charactersWithHyphen->reserveCapacity(string.length() +
                                          hyphenString.length());
    charactersWithHyphen->append(string);
    charactersWithHyphen->append(hyphenString);
    string = charactersWithHyphen->toString();
    maximumLength = string.length();
  }

  ASSERT(maximumLength >= static_cast<int>(string.length()));

  TextRun run(string, textPos().toFloat(), expansion(), expansionBehavior(),
              direction(),
              dirOverride() || style.rtlOrdering() == EOrder::Visual);
  run.setTabSize(!style.collapseWhiteSpace(), style.getTabSize());
  run.setTextJustify(style.getTextJustify());

  // Propagate the maximum length of the characters buffer to the TextRun, even
  // when we're only processing a substring.
  run.setCharactersLength(maximumLength);
  ASSERT(run.charactersLength() >= run.length());
  return run;
}
Пример #5
0
int findNextWordFromIndex(StringView text, int position, bool forward)
{
    TextBreakIterator* it = wordBreakIterator(text);

    if (forward) {
        position = textBreakFollowing(it, position);
        while (position != TextBreakDone) {
            // We stop searching when the character preceeding the break is alphanumeric.
            if (static_cast<unsigned>(position) < text.length() && u_isalnum(text[position - 1]))
                return position;

            position = textBreakFollowing(it, position);
        }

        return text.length();
    } else {
        position = textBreakPreceding(it, position);
        while (position != TextBreakDone) {
            // We stop searching when the character following the break is alphanumeric.
            if (position && u_isalnum(text[position]))
                return position;

            position = textBreakPreceding(it, position);
        }

        return 0;
    }
}
Пример #6
0
 StringView::StringView(const StringView &str, uint32 begin, uint32 end)
     : _str(str.c_str()+begin)
     , _length(end-begin)
 {
     ARC_ASSERT(begin <= str.length(),"Invalid StringView begin.");
     ARC_ASSERT(end <= str.length(), "Invalid StringView end");
 }
Пример #7
0
UCharIterator createIterator(StringView string)
{
    if (string.is8Bit())
        return createLatin1Iterator(string.characters8(), string.length());
    UCharIterator iterator;
    uiter_setString(&iterator, string.characters16(), string.length());
    return iterator;
}
Пример #8
0
static void parseImageCandidatesFromSrcsetAttribute(StringView attribute, Vector<ImageCandidate>& imageCandidates)
{
    // FIXME: We should consider replacing the direct pointers in the parsing process with StringView and positions.
    if (attribute.is8Bit())
        parseImageCandidatesFromSrcsetAttribute<LChar>(attribute.characters8(), attribute.length(), imageCandidates);
    else
        parseImageCandidatesFromSrcsetAttribute<UChar>(attribute.characters16(), attribute.length(), imageCandidates);
}
Пример #9
0
	bool write_string(Slice<char>& buffer, StringView v)
	{
		if (buffer.size() < v.length()) return false;
		
		memcpy(buffer.ptr(), v.c_str(), v.length());
		buffer.trim_front(v.length());
		return true;
	}
static inline bool hostIsInDomain(StringView host, StringView domain)
{
    if (!host.endsWithIgnoringASCIICase(domain))
        return false;

    ASSERT(host.length() >= domain.length());
    unsigned suffixOffset = host.length() - domain.length();
    return suffixOffset == 0 || host[suffixOffset - 1] == '.';
}
Пример #11
0
	size_t add_string(const size_t vertex, const StringView& s, const bool add_substrings = false)
		// extend Trie by one string
		// REQUIRE: all chars in interval [0..alphabet_size]
	{
		size_t v = vertex;
		for (size_t i = 0; i < s.length(); ++i) {
			v = add_char(v, s[i], add_substrings || i == s.length() - 1);
		}
		return v;
	}
Пример #12
0
    void Write(StringView data)
    {
        NEPTOOLS_CHECK(SinkOverflow, offset+buf_put+data.length() <= size,
                       "Sink overflow during write");
        auto cp = std::min(data.length(), size_t(buf_size - buf_put));
        memcpy(buf+buf_put, data.data(), cp);
        data.remove_prefix(cp);
        buf_put += cp;

        if (!data.empty()) Write_(data);
    }
Пример #13
0
v8_inspector::StringView toV8InspectorStringView(const StringView& string) {
  if (string.isNull())
    return v8_inspector::StringView();
  if (string.is8Bit())
    return v8_inspector::StringView(
        reinterpret_cast<const uint8_t*>(string.characters8()),
        string.length());
  return v8_inspector::StringView(
      reinterpret_cast<const uint16_t*>(string.characters16()),
      string.length());
}
Пример #14
0
IDBKeyPathLexer::TokenType IDBKeyPathLexer::lexIdentifier(String& element)
{
    StringView start = m_remainingText;
    if (!m_remainingText.isEmpty() && isIdentifierStartCharacter(m_remainingText[0]))
        m_remainingText = m_remainingText.substring(1);
    else
        return TokenError;

    while (!m_remainingText.isEmpty() && isIdentifierCharacter(m_remainingText[0]))
        m_remainingText = m_remainingText.substring(1);

    element = start.substring(0, start.length() - m_remainingText.length()).toString();
    return TokenIdentifier;
}
Пример #15
0
// https://wicg.github.io/entries-api/#resolve-a-relative-path
static String resolveRelativeVirtualPath(StringView baseVirtualPath, StringView relativeVirtualPath)
{
    ASSERT(baseVirtualPath[0] == '/');
    if (!relativeVirtualPath.isEmpty() && relativeVirtualPath[0] == '/')
        return relativeVirtualPath.length() == 1 ? relativeVirtualPath.toString() : resolveRelativeVirtualPath("/", relativeVirtualPath.substring(1));

    Vector<StringView> virtualPathSegments;
    for (auto segment : baseVirtualPath.split('/'))
        virtualPathSegments.append(segment);

    for (auto segment : relativeVirtualPath.split('/')) {
        ASSERT(!segment.isEmpty());
        if (segment == ".")
            continue;
        if (segment == "..") {
            if (!virtualPathSegments.isEmpty())
                virtualPathSegments.removeLast();
            continue;
        }
        virtualPathSegments.append(segment);
    }

    if (virtualPathSegments.isEmpty())
        return "/"_s;

    StringBuilder builder;
    for (auto& segment : virtualPathSegments) {
        builder.append('/');
        builder.append(segment);
    }
    return builder.toString();
}
Пример #16
0
TextEncoding HTMLMetaCharsetParser::encodingFromMetaAttributes(const AttributeList& attributes)
{
    bool gotPragma = false;
    enum { None, Charset, Pragma } mode = None;
    StringView charset;

    for (auto& attribute : attributes) {
        const String& attributeName = attribute.first;
        const String& attributeValue = attribute.second;

        if (attributeName == http_equivAttr) {
            if (equalIgnoringCase(attributeValue, "content-type"))
                gotPragma = true;
        } else if (charset.isEmpty()) {
            if (attributeName == charsetAttr) {
                charset = attributeValue;
                mode = Charset;
            } else if (attributeName == contentAttr) {
                charset = extractCharset(attributeValue);
                if (charset.length())
                    mode = Pragma;
            }
        }
    }

    if (mode == Charset || (mode == Pragma && gotPragma))
        return TextEncoding(stripLeadingAndTrailingHTMLSpaces(charset.toStringWithoutCopying()));

    return TextEncoding();
}
Пример #17
0
void checkTextOfParagraph(TextCheckerClient& client, StringView text, TextCheckingTypeMask checkingTypes, Vector<TextCheckingResult>& results)
{
#if USE(UNIFIED_TEXT_CHECKING)
    results = client.checkTextOfParagraph(text, checkingTypes);
#else
    Vector<TextCheckingResult> mispellings;
    if (checkingTypes & TextCheckingTypeSpelling)
        findMisspellings(client, text, mispellings);

#if USE(GRAMMAR_CHECKING)
    // Look for grammatical errors that occur before the first misspelling.
    Vector<TextCheckingResult> grammaticalErrors;
    if (checkingTypes & TextCheckingTypeGrammar) {
        unsigned grammarCheckLength = text.length();
        for (auto& mispelling : mispellings)
            grammarCheckLength = std::min<unsigned>(grammarCheckLength, mispelling.location);
        findGrammaticalErrors(client, text.substring(0, grammarCheckLength), grammaticalErrors);
    }

    results = std::move(grammaticalErrors);
#endif

    if (results.isEmpty())
        results = std::move(mispellings);
    else
        results.appendVector(mispellings);
#endif // USE(UNIFIED_TEXT_CHECKING)
}
Пример #18
0
 size_t lastHyphenLocation(const StringView& text,
                           size_t beforeIndex) const override {
   CFIndex result = CFStringGetHyphenationLocationBeforeIndex(
       text.toString().impl()->createCFString().get(), beforeIndex,
       CFRangeMake(0, text.length()), 0, m_localeCF.get(), 0);
   return result == kCFNotFound ? 0 : result;
 }
Пример #19
0
		std::u32string StringToUTF32(const StringView str)
		{
			if (str.empty())
			{
				return std::u32string();
			}

			const wchar* begin = &str[0];
			const wchar* end = begin + str.length();

			if (const auto length = detail::CountCodePoints(begin, end))
			{
				std::u32string result(length.value(), L'\0');

				while (begin != end)
				{
					const auto ch = *begin++;

					if (!IsUTF16Surrogate(ch))
					{
						result.push_back(ch);
					}
					else
					{
						result.push_back(SurrogateToUTF32(ch, *begin++));
					}
				}

				return result;
			}
			else
			{
				return std::u32string();
			}
		}
Пример #20
0
static unsigned nextWordOffset(StringView text, unsigned currentOffset)
{
    // FIXME: avoid creating textIterator object here, it could be passed as a parameter.
    //        isTextBreak() leaves the iterator pointing to the first boundary position at
    //        or after "offset" (ubrk_isBoundary side effect).
    //        For many word separators, the method doesn't properly determine the boundaries
    //        without resetting the iterator.
    TextBreakIterator* textIterator = wordBreakIterator(text);
    if (!textIterator)
        return currentOffset;

    unsigned wordOffset = currentOffset;
    while (wordOffset < text.length() && isTextBreak(textIterator, wordOffset))
        ++wordOffset;

    // Do not treat the word's boundary as a separator.
    if (!currentOffset && wordOffset == 1)
        return currentOffset;

    // Omit multiple separators.
    if ((wordOffset - currentOffset) > 1)
        --wordOffset;

    return wordOffset;
}
Пример #21
0
unsigned numCodeUnitsInGraphemeClusters(StringView string, unsigned numGraphemeClusters)
{
    unsigned stringLength = string.length();

    if (stringLength <= numGraphemeClusters)
        return stringLength;

    // The only Latin-1 Extended Grapheme Cluster is CRLF.
    if (string.is8Bit()) {
        auto* characters = string.characters8();
        unsigned i, j;
        for (i = 0, j = 0; i < numGraphemeClusters && j + 1 < stringLength; ++i, ++j)
            j += characters[j] == '\r' && characters[j + 1] == '\n';
        return j + (i < numGraphemeClusters);
    }

    NonSharedCharacterBreakIterator iterator { string };
    if (!iterator) {
        ASSERT_NOT_REACHED();
        return stringLength;
    }

    for (unsigned i = 0; i < numGraphemeClusters; ++i) {
        if (ubrk_next(iterator) == UBRK_DONE)
            return stringLength;
    }
    return ubrk_current(iterator);
}
Пример #22
0
unsigned numGraphemeClusters(StringView string)
{
    unsigned stringLength = string.length();
    
    if (!stringLength)
        return 0;

    // The only Latin-1 Extended Grapheme Cluster is CRLF.
    if (string.is8Bit()) {
        auto* characters = string.characters8();
        unsigned numCRLF = 0;
        for (unsigned i = 1; i < stringLength; ++i)
            numCRLF += characters[i - 1] == '\r' && characters[i] == '\n';
        return stringLength - numCRLF;
    }

    NonSharedCharacterBreakIterator iterator { string };
    if (!iterator) {
        ASSERT_NOT_REACHED();
        return stringLength;
    }

    unsigned numGraphemeClusters = 0;
    while (ubrk_next(iterator) != UBRK_DONE)
        ++numGraphemeClusters;
    return numGraphemeClusters;
}
Пример #23
0
void processFeaturesString(StringView features, std::function<void(StringView type, StringView value)> callback)
{
    unsigned length = features.length();
    for (unsigned i = 0; i < length; ) {
        // skip to first non-separator
        while (i < length && isSeparator(features[i]))
            ++i;
        unsigned keyBegin = i;

        // skip to first separator
        while (i < length && !isSeparator(features[i]))
            i++;
        unsigned keyEnd = i;

        // skip to first '=', but don't skip past a ','
        while (i < length && features[i] != '=' && features[i] != ',')
            ++i;

        // skip to first non-separator, but don't skip past a ','
        while (i < length && isSeparator(features[i]) && features[i] != ',')
            ++i;
        unsigned valueBegin = i;

        // skip to first separator
        while (i < length && !isSeparator(features[i]))
            ++i;
        unsigned valueEnd = i;

        callback(features.substring(keyBegin, keyEnd - keyBegin), features.substring(valueBegin, valueEnd - valueBegin));
    }
}
void RenderCombineText::getStringToRender(int start, StringView& string, int& length) const
{
    ASSERT(start >= 0);
    if (m_isCombined) {
        string = StringView(originalText());
        length = string.length();
        return;
    }

    string = text().createView(start, length);
}
Пример #25
0
// https://wicg.github.io/entries-api/#path-segment
static bool isValidPathSegment(StringView segment)
{
    if (segment.isEmpty() || segment == "." || segment == "..")
        return true;

    for (unsigned i = 0; i < segment.length(); ++i) {
        if (!isValidPathNameCharacter(segment[i]))
            return false;
    }
    return true;
}
Пример #26
0
String TextCheckingHelper::findFirstMisspelling(int& firstMisspellingOffset, bool markAll, RefPtr<Range>& firstMisspellingRange)
{
    WordAwareIterator it(*m_range);
    firstMisspellingOffset = 0;
    
    String firstMisspelling;
    int currentChunkOffset = 0;

    while (!it.atEnd()) {
        StringView text = it.text();
        int textLength = text.length();

        // Skip some work for one-space-char hunks
        if (textLength == 1 && text[0] == ' ') {
            int misspellingLocation = -1;
            int misspellingLength = 0;
            m_client->textChecker()->checkSpellingOfString(text, &misspellingLocation, &misspellingLength);

            // 5490627 shows that there was some code path here where the String constructor below crashes.
            // We don't know exactly what combination of bad input caused this, so we're making this much
            // more robust against bad input on release builds.
            ASSERT(misspellingLength >= 0);
            ASSERT(misspellingLocation >= -1);
            ASSERT(!misspellingLength || misspellingLocation >= 0);
            ASSERT(misspellingLocation < textLength);
            ASSERT(misspellingLength <= textLength);
            ASSERT(misspellingLocation + misspellingLength <= textLength);

            if (misspellingLocation >= 0 && misspellingLength > 0 && misspellingLocation < textLength && misspellingLength <= textLength && misspellingLocation + misspellingLength <= textLength) {
                // Compute range of misspelled word
                RefPtr<Range> misspellingRange = TextIterator::subrange(m_range.get(), currentChunkOffset + misspellingLocation, misspellingLength);

                // Remember first-encountered misspelling and its offset.
                if (!firstMisspelling) {
                    firstMisspellingOffset = currentChunkOffset + misspellingLocation;
                    firstMisspelling = text.substring(misspellingLocation, misspellingLength).toString();
                    firstMisspellingRange = misspellingRange;
                }

                // Store marker for misspelled word.
                misspellingRange->startContainer()->document().markers().addMarker(misspellingRange.get(), DocumentMarker::Spelling);

                // Bail out if we're marking only the first misspelling, and not all instances.
                if (!markAll)
                    break;
            }
        }
        
        currentChunkOffset += textLength;
        it.advance();
    }
    
    return firstMisspelling;
}
Пример #27
0
String createStringWithMirroredCharacters(StringView string)
{
    unsigned length = string.length();
    StringBuilder mirroredCharacters;
    mirroredCharacters.reserveCapacity(length);
    for (unsigned i = 0; i < length; ) {
        UChar32 character;
        U16_NEXT(string, i, length, character);
        mirroredCharacters.append(u_charMirror(character));
    }
    return mirroredCharacters.toString();
}
Пример #28
0
unsigned startOfLastWordBoundaryContext(StringView text)
{
    unsigned length = text.length();
    for (unsigned i = length; i > 0; ) {
        unsigned last = i;
        UChar32 ch;
        U16_PREV(text, 0, i, ch);
        if (!requiresContextForWordBoundary(ch))
            return last;
    }
    return 0;
}
Пример #29
0
unsigned endOfFirstWordBoundaryContext(StringView text)
{
    unsigned length = text.length();
    for (unsigned i = 0; i < length; ) {
        unsigned first = i;
        UChar32 ch;
        U16_NEXT(text, i, length, ch);
        if (!requiresContextForWordBoundary(ch))
            return first;
    }
    return length;
}
Пример #30
0
void WebEditorClient::checkSpellingOfString(StringView text, int* misspellingLocation, int* misspellingLength)
{
    *misspellingLocation = -1;
    *misspellingLength = 0;

    COMPtr<IWebEditingDelegate> ed;
    if (FAILED(m_webView->editingDelegate(&ed)) || !ed.get())
        return;

    initViewSpecificSpelling(m_webView);
    ed->checkSpellingOfString(m_webView, text.upconvertedCharacters(), text.length(), misspellingLocation, misspellingLength);
}