Commit message: None
CVE: CVE-2013-2878
CWE: CWE-119
Vulnerability description: Google Chrome before 28.0.1500.71 allows remote attackers to cause a denial of service (out-of-bounds read) via vectors related to the handling of text.

Project: Chrome

TextIterator::TextIterator(const Range* r, TextIteratorBehavior behavior)
    : m_startContainer(0)
    , m_startOffset(0)
    , m_endContainer(0)
    , m_endOffset(0)
    , m_positionNode(0)
    , m_textCharacters(0)
    , m_textLength(0)
    , m_remainingTextBox(0)
    , m_firstLetterText(0)
    , m_sortedTextBoxesPosition(0)
    , m_emitsCharactersBetweenAllVisiblePositions(behavior & TextIteratorEmitsCharactersBetweenAllVisiblePositions)
    , m_entersTextControls(behavior & TextIteratorEntersTextControls)
    , m_emitsTextWithoutTranscoding(behavior & TextIteratorEmitsTextsWithoutTranscoding)
    , m_emitsOriginalText(behavior & TextIteratorEmitsOriginalText)
    , m_handledFirstLetter(false)
    , m_ignoresStyleVisibility(behavior & TextIteratorIgnoresStyleVisibility)
    , m_emitsObjectReplacementCharacters(behavior & TextIteratorEmitsObjectReplacementCharacters)
    , m_stopsOnFormControls(behavior & TextIteratorStopsOnFormControls)
    , m_shouldStop(false)
    , m_emitsImageAltText(behavior & TextIteratorEmitsImageAltText)
{
    if (!r)
        return;

    Node* startContainer = r->startContainer();
    if (!startContainer)
        return;
    int startOffset = r->startOffset();
    Node* endContainer = r->endContainer();
    int endOffset = r->endOffset();

    ASSERT(r->boundaryPointsValid());

    m_startContainer = startContainer;
    m_startOffset = startOffset;
    m_endContainer = endContainer;
    m_endOffset = endOffset;

    m_node = r->firstNode();
    if (!m_node)
        return;
    setUpFullyClippedStack(m_fullyClippedStack, m_node);
    m_offset = m_node == m_startContainer ? m_startOffset : 0;
    m_handledNode = false;
    m_handledChildren = false;

    m_pastEndNode = nextInPreOrderCrossingShadowBoundaries(endContainer, endOffset);

    m_needsAnotherNewline = false;
    m_textBox = 0;

    m_hasEmitted = false;
    m_lastTextNode = 0;
    m_lastTextNodeEndedWithCollapsedSpace = false;
    m_lastCharacter = 0;

#ifndef NDEBUG
    m_positionNode = m_node;
#endif

    advance();
}

Project: Chrome

void TextIterator::exitNode()
{
    if (!m_hasEmitted)
        return;
        
    Node* baseNode = m_node->lastChild() ? m_node->lastChild() : m_node;
    if (m_lastTextNode && shouldEmitNewlineAfterNode(m_node)) {
        bool addNewline = shouldEmitExtraNewlineForNode(m_node);
        
        if (m_lastCharacter != '\n') {
            emitCharacter('\n', baseNode->parentNode(), baseNode, 1, 1);
            ASSERT(!m_needsAnotherNewline);
            m_needsAnotherNewline = addNewline;
        } else if (addNewline)
            emitCharacter('\n', baseNode->parentNode(), baseNode, 1, 1);
    }
    
    if (!m_positionNode && shouldEmitSpaceBeforeAndAfterNode(m_node))
        emitCharacter(' ', baseNode->parentNode(), baseNode, 1, 1);
}

Project: Chrome

inline bool SearchBuffer::isBadMatch(const UChar* match, size_t matchLength) const
{
    if (!m_targetRequiresKanaWorkaround)
        return false;

    normalizeCharacters(match, matchLength, m_normalizedMatch);

    const UChar* a = m_normalizedTarget.begin();
    const UChar* aEnd = m_normalizedTarget.end();

    const UChar* b = m_normalizedMatch.begin();
    const UChar* bEnd = m_normalizedMatch.end();

    while (true) {
        while (a != aEnd && !isKanaLetter(*a))
            ++a;
        while (b != bEnd && !isKanaLetter(*b))
            ++b;

        if (a == aEnd || b == bEnd) {
            ASSERT(a == aEnd);
            ASSERT(b == bEnd);
            return false;
        }

        if (isSmallKanaLetter(*a) != isSmallKanaLetter(*b))
            return true;
        if (composedVoicedSoundMark(*a) != composedVoicedSoundMark(*b))
            return true;
        ++a;
        ++b;

        while (1) {
            if (!(a != aEnd && isCombiningVoicedSoundMark(*a))) {
                if (b != bEnd && isCombiningVoicedSoundMark(*b))
                    return true;
                break;
            }
            if (!(b != bEnd && isCombiningVoicedSoundMark(*b)))
                return true;
            if (*a != *b)
                return true;
            ++a;
            ++b;
        }
    }
}

Project: Chrome

static bool shouldEmitNewlineAfterNode(Node* node)
{
    if (!shouldEmitNewlinesBeforeAndAfterNode(node))
        return false;
    while ((node = NodeTraversal::nextSkippingChildren(node)))
        if (node->renderer())
            return true;
    return false;
}

Project: Chrome

TextIterator::~TextIterator()
{
}