Ignore:
Timestamp:
Dec 1, 2014, 9:50:35 AM (10 years ago)
Author:
[email protected]
Message:

Make sure range based iteration of Vector<> still receives bounds checking
https://bugs.webkit.org/show_bug.cgi?id=138821

Reviewed by Mark Lam.

Source/JavaScriptCore:

There are a few uses of begin()/end() that explicitly require pointers,
so we use getPtr() to extract the underlying pointer generically.

  • bytecode/UnlinkedCodeBlock.cpp:

(JSC::UnlinkedCodeBlock::visitChildren):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitComplexPopScopes):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::emitSwitchIntJump):

  • ftl/FTLAbbreviations.h:

(JSC::FTL::mdNode):
(JSC::FTL::buildCall):

  • llint/LLIntData.cpp:

(JSC::LLInt::Data::performAssertions):

  • parser/Parser.h:

(JSC::Scope::Scope):

  • profiler/ProfileNode.cpp:

(JSC::ProfileNode::debugPrintRecursively):

  • runtime/JSArray.cpp:

(JSC::JSArray::setLengthWithArrayStorage):
(JSC::JSArray::sortCompactedVector):

  • tools/ProfileTreeNode.h:

(JSC::ProfileTreeNode::dumpInternal):

  • yarr/YarrJIT.cpp:

(JSC::Yarr::YarrGenerator::matchCharacterClass):

Source/WebCore:

There are a few uses of begin()/end() that explicitly require pointers,
so we use getPtr() to extract the underlying pointer generically.

  • bindings/js/SerializedScriptValue.cpp:

(WebCore::CloneDeserializer::deserializeString):

  • editing/TextIterator.cpp:

(WebCore::SearchBuffer::isBadMatch):

  • page/mac/ServicesOverlayController.mm:

(WebCore::ServicesOverlayController::buildSelectionHighlight):

  • platform/graphics/SegmentedFontData.cpp:

(WebCore::SegmentedFontData::fontDataForCharacter):
(WebCore::SegmentedFontData::containsCharacter):
(WebCore::SegmentedFontData::isLoading):

  • platform/graphics/WOFFFileFormat.cpp:

(WebCore::convertWOFFToSfnt):

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::paintFillLayers):

  • rendering/style/GridResolvedPosition.cpp:

(WebCore::firstNamedGridLineBeforePosition):
(WebCore::GridResolvedPosition::resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition):

  • svg/SVGFontElement.cpp:

(WebCore::kerningForPairOfStringsAndGlyphs):

  • svg/SVGPathByteStream.h:

(WebCore::SVGPathByteStream::append):

  • xml/XPathNodeSet.h:

(WebCore::XPath::NodeSet::begin):
(WebCore::XPath::NodeSet::end):

Source/WTF:

Add a new IndexedIterator struct to WTF that wraps a
Vector type and index to provide pointer like semantics
while still performing runtime bounds checking, even in
release builds. We store a simple index into the vector
which means that this iterator allows vector resizing
during iteration. If the vector is resized such that the
iterator is out of bounds, then any attempt to dereference
the iterator will crash safely. Any other errors, including
overflows, and over extending the iterator will likewise
crash.

For the purpose of retaining semantically equivalent
behaviour, the iterator can be moved to m_index == size()
as that is the standard "end" terminator for these types.
Attempting to dereference at that point will still crash
rather than perform an unsafe memory operation.

In order to maintain the validity of all the bounds checking,
we perform full integer range checking prior to any mutation
of the iterator location. If we detect an arithmetic overflow
we will crash rather than attempting to carry on.

By necessity there are many overrides for operator + and - as
we otherwise hit many different type promotion ambiguities when
performing arithmetic with iterators. These ambiguities are also
different for 32- vs. 64-bit, so duplicating the functions
and then forwarding to the core implementations that performed
the bounds checking and mutation seemed like the right call.

  • WTF.xcodeproj/project.pbxproj:
  • wtf/IndexedIterator.h: Added.

(WTF::IndexedIterator::IndexedIterator):
(WTF::IndexedIterator::operator->):
(WTF::IndexedIterator::operator*):
(WTF::IndexedIterator::get):
(WTF::IndexedIterator::operator++):
(WTF::IndexedIterator::operator--):
(WTF::IndexedIterator::operator UnspecifiedBoolType):
(WTF::IndexedIterator::operator+=):
(WTF::IndexedIterator::operator-=):
(WTF::IndexedIterator::operator+):
(WTF::IndexedIterator::operator-):
(WTF::IndexedIterator::operator=):
(WTF::IndexedIterator::operator==):
(WTF::IndexedIterator::operator!=):
(WTF::IndexedIterator::operator<):
(WTF::IndexedIterator::operator<=):
(WTF::IndexedIterator::operator>):
(WTF::IndexedIterator::operator>=):
(WTF::IndexedIterator::operator const_iterator):
(WTF::IndexedIterator::isSafeToCompare):
(WTF::IndexedIterator::unsafeGet):
(WTF::getPtr):
(WTF::operator-):
(WTF::operator==):
(WTF::operator!=):
(WTF::operator<=):
(WTF::operator>=):
(WTF::operator<):
(WTF::operator>):
(WTF::IndexedIteratorSelector::makeIterator):
(WTF::IndexedIteratorSelector::makeConstIterator):

  • wtf/RefCountedArray.h:

(WTF::RefCountedArray::RefCountedArray):

  • wtf/Vector.h:

(WTF::Vector::Vector):
(WTF::Vector::begin):
(WTF::Vector::end):
(WTF::OverflowHandler>::Vector):
(WTF::=):
(WTF::OverflowHandler>::fill):
(WTF::OverflowHandler>::expandCapacity):
(WTF::OverflowHandler>::tryExpandCapacity):
(WTF::OverflowHandler>::resize):
(WTF::OverflowHandler>::shrink):
(WTF::OverflowHandler>::grow):
(WTF::OverflowHandler>::reserveCapacity):
(WTF::OverflowHandler>::tryReserveCapacity):
(WTF::OverflowHandler>::shrinkCapacity):
(WTF::OverflowHandler>::append):
(WTF::OverflowHandler>::tryAppend):
(WTF::OverflowHandler>::appendSlowCase):
(WTF::OverflowHandler>::uncheckedAppend):
(WTF::OverflowHandler>::appendVector):
(WTF::OverflowHandler>::insert):
(WTF::OverflowHandler>::insertVector):
(WTF::OverflowHandler>::remove):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r175396 r176592  
    131131        if (rhs.m_labels) {
    132132            m_labels = adoptPtr(new LabelStack);
    133 
    134             typedef LabelStack::const_iterator iterator;
    135             iterator end = rhs.m_labels->end();
    136             for (iterator it = rhs.m_labels->begin(); it != end; ++it)
    137                 m_labels->append(ScopeLabelInfo(it->m_ident, it->m_isLoop));
     133            for (auto label : *rhs.m_labels)
     134                m_labels->append(ScopeLabelInfo(label.m_ident, label.m_isLoop));
    138135        }
    139136    }
Note: See TracChangeset for help on using the changeset viewer.