Changeset 259832 in webkit
- Timestamp:
- Apr 9, 2020, 2:55:53 PM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
-
ChangeLog (modified) (1 diff)
-
accessibility/isolatedtree/AXIsolatedTree.cpp (modified) (5 diffs)
-
accessibility/mac/WebAccessibilityObjectWrapperBase.mm (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r259830 r259832 1 2020-04-09 Andres Gonzalez <andresg_22@apple.com> 2 3 Fix for crash in test accessibility/mac/aria-grid-with-strange-hierarchy.html in isolated tree mode. 4 https://bugs.webkit.org/show_bug.cgi?id=210295 5 6 Reviewed by Chris Fleizach. 7 8 Covered by accessibility/mac/aria-grid-with-strange-hierarchy.html. 9 10 - When AXIsolatedTree::applyPendingChanges encounters a change for an 11 already existing object, the existing object is discarded and the new 12 object replaces it in the nodes map. The existing and new objects must 13 have the same platform wrapper. Thus the wrapper needs to be detached 14 from the existing object about to be discarded, and re-attached to the 15 new object. We were missing the re-attachment, and hence the crash when 16 the wrapper tries to access its underlying object. 17 - In addition, moved the LockHolder in a couple of intances to before 18 AXIsolatedTree::nodeForID, because this method accesses a member 19 variable used in both threads. 20 - Added stricter assert checks to catch problems with the management of 21 objects and wrappers during tree updates. 22 23 * accessibility/isolatedtree/AXIsolatedTree.cpp: 24 (WebCore::AXIsolatedTree::updateNode): 25 (WebCore::AXIsolatedTree::updateChildren): 26 (WebCore::AXIsolatedTree::applyPendingChanges): 27 * accessibility/mac/WebAccessibilityObjectWrapperBase.mm: 28 (-[WebAccessibilityObjectWrapperBase attachIsolatedObject:]): 29 1 30 2020-04-09 Said Abou-Hallawa <sabouhallawa@apple.com> 2 31 -
trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp
r258971 r259832 187 187 AXID parentID = axParent ? axParent->objectID() : InvalidAXID; 188 188 189 LockHolder locker { m_changeLogLock }; 189 190 if (auto object = nodeForID(axID)) { 190 191 ASSERT(object->objectID() == axID); 191 192 auto newObject = AXIsolatedObject::create(axObject, m_treeID, parentID); 192 193 193 LockHolder locker { m_changeLogLock };194 194 // The new object should have the same children as the old one. 195 195 newObject->m_childrenIDs = object->m_childrenIDs; … … 213 213 ASSERT(isMainThread()); 214 214 AXID axObjectID = axObject.objectID(); 215 216 LockHolder locker { m_changeLogLock }; 215 217 auto object = nodeForID(axObjectID); 216 218 if (!object) 217 219 return; // nothing to update. 218 220 221 auto removals = object->m_childrenIDs; 222 locker.unlockEarly(); 223 219 224 const auto& axChildren = axObject.children(); 220 225 auto axChildrenIDs = axObject.childrenIDs(); 221 222 LockHolder locker { m_changeLogLock };223 auto removals = object->m_childrenIDs;224 // Make the children IDs of the isolated object to be the same as the AXObject's.225 object->m_childrenIDs = axChildrenIDs;226 locker.unlockEarly();227 226 228 227 for (size_t i = 0; i < axChildrenIDs.size(); ++i) { … … 232 231 else { 233 232 // This is a new child, add it to the tree. 234 generateSubtree(*axChildren[i], axObjectID, false);233 generateSubtree(*axChildren[i], axObjectID, true); 235 234 } 236 235 } … … 240 239 for (const AXID& childID : removals) 241 240 removeSubtree(childID); 241 242 { 243 // Lastly, make the children IDs of the isolated object to be the same as the AXObject's. 244 LockHolder locker { m_changeLogLock }; 245 object->m_childrenIDs = axChildrenIDs; 246 } 242 247 } 243 248 … … 332 337 333 338 for (const auto& item : m_pendingAppends) { 334 ASSERT(item.m_isolatedObject->wrapper() || item.m_wrapper); 339 // Either the new object has a wrapper already attached, or one is passed to be attached, not both. 340 ASSERT((item.m_isolatedObject->wrapper() || item.m_wrapper) 341 && !(item.m_isolatedObject->wrapper() && item.m_wrapper)); 335 342 AXID axID = item.m_isolatedObject->objectID(); 336 343 if (axID == InvalidAXID) 337 344 continue; 338 345 346 auto& wrapper = item.m_wrapper ? item.m_wrapper : item.m_isolatedObject->wrapper(); 347 339 348 if (auto object = m_readerThreadNodeMap.get(axID)) { 340 349 if (object != &item.m_isolatedObject.get() 341 && (object->wrapper() == item.m_wrapper || object->wrapper() == item.m_isolatedObject->wrapper())) {350 && object->wrapper() == wrapper.get()) { 342 351 // The new IsolatedObject is a replacement for an existing object 343 // as the result of an update. Thus detach the existing one before344 // addingthe new one.352 // as the result of an update. Thus detach the wrapper from the 353 // existing object and attach it to the new one. 345 354 object->detachWrapper(AccessibilityDetachmentType::ElementDestroyed); 355 item.m_isolatedObject->attachPlatformWrapper(wrapper.get()); 346 356 } 347 357 m_readerThreadNodeMap.remove(axID); 348 358 } 349 359 350 if (m_readerThreadNodeMap.add(axID, item.m_isolatedObject.get()) && item.m_wrapper) 351 m_readerThreadNodeMap.get(axID)->attachPlatformWrapper(item.m_wrapper.get()); 352 360 if (!item.m_isolatedObject->wrapper()) { 361 // The new object hasn't been attached a wrapper yet, so attach it. 362 item.m_isolatedObject->attachPlatformWrapper(wrapper.get()); 363 } 364 365 auto addResult = m_readerThreadNodeMap.add(axID, item.m_isolatedObject.get()); 366 // The newly added object must have a wrapper. 367 ASSERT_UNUSED(addResult, addResult.iterator->value->wrapper()); 353 368 // The reference count of the just added IsolatedObject must be 2 354 369 // because it is referenced by m_readerThreadNodeMap and m_pendingAppends. 355 370 // When m_pendingAppends is cleared, the object will be held only by m_readerThreadNodeMap. 356 ASSERT (m_readerThreadNodeMap.get(axID)->refCount() == 2);371 ASSERT_UNUSED(addResult, addResult.iterator->value->refCount() == 2); 357 372 } 358 373 m_pendingAppends.clear(); -
trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperBase.mm
r258115 r259832 305 305 { 306 306 ASSERT(isolatedObject && (_identifier == InvalidAXID || _identifier == isolatedObject->objectID())); 307 ASSERT(m_axObject && isolatedObject->objectID() == m_axObject->objectID()); 307 308 m_isolatedObject = isolatedObject; 308 309 if (_identifier == InvalidAXID)
Note:
See TracChangeset
for help on using the changeset viewer.