Changeset 257389 in webkit
- Timestamp:
- Feb 25, 2020 4:20:21 PM (4 years ago)
- Location:
- trunk/Source/WebKit
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r257386 r257389 1 2020-02-25 Chris Dumez <cdumez@apple.com> 2 3 Make sure a client cannot cause a whole DOM tree to get leaked by simply holding on to a WKBundleNodeHandle 4 https://bugs.webkit.org/show_bug.cgi?id=208218 5 6 Reviewed by Ryosuke Niwa. 7 8 Make sure a client cannot cause a whole DOM tree to get leaked by simply holding on to a WKBundleNodeHandle. 9 Previously, WKBundleNodeHandle would ref its node, which would keep the whole HTML document alive. To protect 10 against this, InjectedBundleNodeHandle is now an ActiveDOMObject which nulls out its node RefPtr when the 11 document is getting ready for destruction (i.e. ActiveDOMObject::stop() is called). 12 13 * WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp: 14 (WebKit::InjectedBundleNodeHandle::InjectedBundleNodeHandle): 15 (WebKit::InjectedBundleNodeHandle::~InjectedBundleNodeHandle): 16 (WebKit::InjectedBundleNodeHandle::coreNode): 17 (WebKit::InjectedBundleNodeHandle::document): 18 (WebKit::InjectedBundleNodeHandle::elementBounds): 19 (WebKit::InjectedBundleNodeHandle::renderRect): 20 (WebKit::InjectedBundleNodeHandle::renderedImage): 21 (WebKit::InjectedBundleNodeHandle::visibleRange): 22 (WebKit::InjectedBundleNodeHandle::setHTMLInputElementValueForUser): 23 (WebKit::InjectedBundleNodeHandle::setHTMLInputElementSpellcheckEnabled): 24 (WebKit::InjectedBundleNodeHandle::isHTMLInputElementAutoFilled const): 25 (WebKit::InjectedBundleNodeHandle::isHTMLInputElementAutoFilledAndViewable const): 26 (WebKit::InjectedBundleNodeHandle::setHTMLInputElementAutoFilled): 27 (WebKit::InjectedBundleNodeHandle::setHTMLInputElementAutoFilledAndViewable): 28 (WebKit::InjectedBundleNodeHandle::isHTMLInputElementAutoFillButtonEnabled const): 29 (WebKit::InjectedBundleNodeHandle::setHTMLInputElementAutoFillButtonEnabled): 30 (WebKit::InjectedBundleNodeHandle::htmlInputElementAutoFillButtonType const): 31 (WebKit::InjectedBundleNodeHandle::htmlInputElementLastAutoFillButtonType const): 32 (WebKit::InjectedBundleNodeHandle::isAutoFillAvailable const): 33 (WebKit::InjectedBundleNodeHandle::setAutoFillAvailable): 34 (WebKit::InjectedBundleNodeHandle::htmlInputElementAutoFillButtonBounds): 35 (WebKit::InjectedBundleNodeHandle::htmlInputElementLastChangeWasUserEdit): 36 (WebKit::InjectedBundleNodeHandle::htmlTextAreaElementLastChangeWasUserEdit): 37 (WebKit::InjectedBundleNodeHandle::isTextField const): 38 (WebKit::InjectedBundleNodeHandle::htmlTableCellElementCellAbove): 39 (WebKit::InjectedBundleNodeHandle::documentFrame): 40 (WebKit::InjectedBundleNodeHandle::htmlFrameElementContentFrame): 41 (WebKit::InjectedBundleNodeHandle::htmlIFrameElementContentFrame): 42 (WebKit::InjectedBundleNodeHandle::stop): 43 (WebKit::InjectedBundleNodeHandle::activeDOMObjectName const): 44 * WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.h: 45 1 46 2020-02-25 Youenn Fablet <youenn@apple.com> 2 47 -
trunk/Source/WebKit/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp
r249175 r257389 100 100 101 101 InjectedBundleNodeHandle::InjectedBundleNodeHandle(Node& node) 102 : m_node(node) 102 : ActiveDOMObject(node.document()) 103 , m_node(&node) 103 104 { 104 105 } … … 106 107 InjectedBundleNodeHandle::~InjectedBundleNodeHandle() 107 108 { 108 domNodeHandleCache().remove(m_node.ptr()); 109 if (m_node) 110 domNodeHandleCache().remove(m_node.get()); 109 111 } 110 112 111 113 Node* InjectedBundleNodeHandle::coreNode() 112 114 { 113 return m_node.ptr(); 114 } 115 116 Ref<InjectedBundleNodeHandle> InjectedBundleNodeHandle::document() 117 { 115 return m_node.get(); 116 } 117 118 RefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::document() 119 { 120 if (!m_node) 121 return nullptr; 122 118 123 return getOrCreate(m_node->document()); 119 124 } … … 127 132 return IntRect(); 128 133 129 return downcast<Element>( m_node.get()).boundsInRootViewSpace();134 return downcast<Element>(*m_node).boundsInRootViewSpace(); 130 135 } 131 136 132 137 IntRect InjectedBundleNodeHandle::renderRect(bool* isReplaced) 133 138 { 139 if (!m_node) 140 return { }; 141 134 142 return m_node->pixelSnappedRenderRect(isReplaced); 135 143 } … … 189 197 RefPtr<WebImage> InjectedBundleNodeHandle::renderedImage(SnapshotOptions options, bool shouldExcludeOverflow, const Optional<float>& bitmapWidth) 190 198 { 199 if (!m_node) 200 return nullptr; 201 191 202 Frame* frame = m_node->document().frame(); 192 203 if (!frame) … … 211 222 } 212 223 213 frameView->setNodeToDraw(m_node. ptr());224 frameView->setNodeToDraw(m_node.get()); 214 225 auto image = imageForRect(frameView, paintingRect, bitmapWidth, options); 215 226 frameView->setNodeToDraw(0); … … 220 231 RefPtr<InjectedBundleRangeHandle> InjectedBundleNodeHandle::visibleRange() 221 232 { 222 VisiblePosition start = firstPositionInNode(m_node.ptr()); 223 VisiblePosition end = lastPositionInNode(m_node.ptr()); 233 if (!m_node) 234 return nullptr; 235 236 VisiblePosition start = firstPositionInNode(m_node.get()); 237 VisiblePosition end = lastPositionInNode(m_node.get()); 224 238 225 239 RefPtr<Range> range = makeRange(start, end); … … 232 246 return; 233 247 234 downcast<HTMLInputElement>( m_node.get()).setValueForUser(value);248 downcast<HTMLInputElement>(*m_node).setValueForUser(value); 235 249 } 236 250 … … 240 254 return; 241 255 242 downcast<HTMLInputElement>( m_node.get()).setSpellcheckDisabledExceptTextReplacement(!enabled);256 downcast<HTMLInputElement>(*m_node).setSpellcheckDisabledExceptTextReplacement(!enabled); 243 257 } 244 258 … … 248 262 return false; 249 263 250 return downcast<HTMLInputElement>( m_node.get()).isAutoFilled();264 return downcast<HTMLInputElement>(*m_node).isAutoFilled(); 251 265 } 252 266 … … 256 270 return false; 257 271 258 return downcast<HTMLInputElement>( m_node.get()).isAutoFilledAndViewable();272 return downcast<HTMLInputElement>(*m_node).isAutoFilledAndViewable(); 259 273 } 260 274 … … 264 278 return; 265 279 266 downcast<HTMLInputElement>( m_node.get()).setAutoFilled(filled);280 downcast<HTMLInputElement>(*m_node).setAutoFilled(filled); 267 281 } 268 282 … … 272 286 return; 273 287 274 downcast<HTMLInputElement>( m_node.get()).setAutoFilledAndViewable(autoFilledAndViewable);288 downcast<HTMLInputElement>(*m_node).setAutoFilledAndViewable(autoFilledAndViewable); 275 289 } 276 290 … … 280 294 return false; 281 295 282 return downcast<HTMLInputElement>( m_node.get()).autoFillButtonType() != AutoFillButtonType::None;296 return downcast<HTMLInputElement>(*m_node).autoFillButtonType() != AutoFillButtonType::None; 283 297 } 284 298 … … 288 302 return; 289 303 290 downcast<HTMLInputElement>( m_node.get()).setShowAutoFillButton(autoFillButtonType);304 downcast<HTMLInputElement>(*m_node).setShowAutoFillButton(autoFillButtonType); 291 305 } 292 306 … … 295 309 if (!is<HTMLInputElement>(m_node)) 296 310 return AutoFillButtonType::None; 297 return downcast<HTMLInputElement>( m_node.get()).autoFillButtonType();311 return downcast<HTMLInputElement>(*m_node).autoFillButtonType(); 298 312 } 299 313 … … 302 316 if (!is<HTMLInputElement>(m_node)) 303 317 return AutoFillButtonType::None; 304 return downcast<HTMLInputElement>( m_node.get()).lastAutoFillButtonType();318 return downcast<HTMLInputElement>(*m_node).lastAutoFillButtonType(); 305 319 } 306 320 … … 310 324 return false; 311 325 312 return downcast<HTMLInputElement>( m_node.get()).isAutoFillAvailable();326 return downcast<HTMLInputElement>(*m_node).isAutoFillAvailable(); 313 327 } 314 328 … … 318 332 return; 319 333 320 downcast<HTMLInputElement>( m_node.get()).setAutoFillAvailable(autoFillAvailable);334 downcast<HTMLInputElement>(*m_node).setAutoFillAvailable(autoFillAvailable); 321 335 } 322 336 … … 326 340 return IntRect(); 327 341 328 auto autoFillButton = downcast<HTMLInputElement>( m_node.get()).autoFillButtonElement();342 auto autoFillButton = downcast<HTMLInputElement>(*m_node).autoFillButtonElement(); 329 343 if (!autoFillButton) 330 344 return IntRect(); … … 338 352 return false; 339 353 340 return downcast<HTMLInputElement>( m_node.get()).lastChangeWasUserEdit();354 return downcast<HTMLInputElement>(*m_node).lastChangeWasUserEdit(); 341 355 } 342 356 … … 346 360 return false; 347 361 348 return downcast<HTMLTextAreaElement>( m_node.get()).lastChangeWasUserEdit();362 return downcast<HTMLTextAreaElement>(*m_node).lastChangeWasUserEdit(); 349 363 } 350 364 … … 354 368 return false; 355 369 356 return downcast<HTMLInputElement>( m_node.get()).isTextField();370 return downcast<HTMLInputElement>(*m_node).isTextField(); 357 371 } 358 372 … … 367 381 return nullptr; 368 382 369 return getOrCreate(downcast<HTMLTableCellElement>( m_node.get()).cellAbove());383 return getOrCreate(downcast<HTMLTableCellElement>(*m_node).cellAbove()); 370 384 } 371 385 372 386 RefPtr<WebFrame> InjectedBundleNodeHandle::documentFrame() 373 387 { 374 if (!m_node ->isDocumentNode())375 return nullptr; 376 377 Frame* frame = downcast<Document>( m_node.get()).frame();388 if (!m_node || !m_node->isDocumentNode()) 389 return nullptr; 390 391 Frame* frame = downcast<Document>(*m_node).frame(); 378 392 if (!frame) 379 393 return nullptr; … … 387 401 return nullptr; 388 402 389 Frame* frame = downcast<HTMLFrameElement>( m_node.get()).contentFrame();403 Frame* frame = downcast<HTMLFrameElement>(*m_node).contentFrame(); 390 404 if (!frame) 391 405 return nullptr; … … 399 413 return nullptr; 400 414 401 Frame* frame = downcast<HTMLIFrameElement>( m_node.get()).contentFrame();415 Frame* frame = downcast<HTMLIFrameElement>(*m_node).contentFrame(); 402 416 if (!frame) 403 417 return nullptr; … … 406 420 } 407 421 422 void InjectedBundleNodeHandle::stop() 423 { 424 // Invalidate handles to nodes inside documents that are about to be destroyed in order to prevent leaks. 425 if (m_node) { 426 domNodeHandleCache().remove(m_node.get()); 427 m_node = nullptr; 428 } 429 } 430 431 const char* InjectedBundleNodeHandle::activeDOMObjectName() const 432 { 433 return "InjectedBundleNodeHandle"; 434 } 435 408 436 } // namespace WebKit -
trunk/Source/WebKit/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.h
r248373 r257389 29 29 #include "ImageOptions.h" 30 30 #include <JavaScriptCore/JSBase.h> 31 #include <WebCore/ActiveDOMObject.h> 31 32 #include <wtf/Forward.h> 32 33 #include <wtf/Optional.h> … … 46 47 class WebImage; 47 48 48 class InjectedBundleNodeHandle : public API::ObjectImpl<API::Object::Type::BundleNodeHandle> {49 class InjectedBundleNodeHandle : public API::ObjectImpl<API::Object::Type::BundleNodeHandle>, public WebCore::ActiveDOMObject { 49 50 public: 50 51 static RefPtr<InjectedBundleNodeHandle> getOrCreate(JSContextRef, JSObjectRef); … … 57 58 58 59 // Convenience DOM Operations 59 Ref <InjectedBundleNodeHandle> document();60 RefPtr<InjectedBundleNodeHandle> document(); 60 61 61 62 // Additional DOM Operations … … 93 94 InjectedBundleNodeHandle(WebCore::Node&); 94 95 95 Ref<WebCore::Node> m_node; 96 // ActiveDOMObject. 97 void stop() final; 98 const char* activeDOMObjectName() const final; 99 100 RefPtr<WebCore::Node> m_node; 96 101 }; 97 102
Note: See TracChangeset
for help on using the changeset viewer.