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):
(JSC::FTL::mdNode):
(JSC::FTL::buildCall):
(JSC::LLInt::Data::performAssertions):
(JSC::Scope::Scope):
- profiler/ProfileNode.cpp:
(JSC::ProfileNode::debugPrintRecursively):
(JSC::JSArray::setLengthWithArrayStorage):
(JSC::JSArray::sortCompactedVector):
(JSC::ProfileTreeNode::dumpInternal):
(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):
(WebCore::RenderBox::paintFillLayers):
- rendering/style/GridResolvedPosition.cpp:
(WebCore::firstNamedGridLineBeforePosition):
(WebCore::GridResolvedPosition::resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition):
(WebCore::kerningForPairOfStringsAndGlyphs):
(WebCore::SVGPathByteStream::append):
(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::RefCountedArray):
(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):