| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/dom/MutationObserver.h" | 5 #include "core/dom/MutationObserver.h" |
| 6 | 6 |
| 7 #include "core/dom/MutationCallback.h" | 7 #include "core/dom/MutationCallback.h" |
| 8 #include "core/dom/MutationObserverInit.h" | 8 #include "core/dom/MutationObserverInit.h" |
| 9 #include "core/dom/MutationObserverRegistration.h" | 9 #include "core/dom/MutationObserverRegistration.h" |
| 10 #include "core/html/HTMLDocument.h" | 10 #include "core/html/HTMLDocument.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 MutationCallback::Trace(visitor); | 23 MutationCallback::Trace(visitor); |
| 24 } | 24 } |
| 25 | 25 |
| 26 private: | 26 private: |
| 27 void Call(const HeapVector<Member<MutationRecord>>&, | 27 void Call(const HeapVector<Member<MutationRecord>>&, |
| 28 MutationObserver*) override {} | 28 MutationObserver*) override {} |
| 29 ExecutionContext* GetExecutionContext() const override { return document_; } | 29 ExecutionContext* GetExecutionContext() const override { return document_; } |
| 30 | 30 |
| 31 Member<Document> document_; | 31 Member<Document> document_; |
| 32 }; | 32 }; |
| 33 } | 33 } // namespace |
| 34 | 34 |
| 35 TEST(MutationObserverTest, DisconnectCrash) { | 35 TEST(MutationObserverTest, DisconnectCrash) { |
| 36 Persistent<Document> document = HTMLDocument::Create(); | 36 Persistent<Document> document = HTMLDocument::Create(); |
| 37 HTMLElement* root = ToHTMLElement(document->createElement("html")); | 37 HTMLElement* root = ToHTMLElement(document->createElement("html")); |
| 38 document->AppendChild(root); | 38 document->AppendChild(root); |
| 39 root->setInnerHTML("<head><title>\n</title></head><body></body>"); | 39 root->setInnerHTML("<head><title>\n</title></head><body></body>"); |
| 40 Node* head = root->firstChild()->firstChild(); | 40 Node* head = root->firstChild()->firstChild(); |
| 41 DCHECK(head); | 41 DCHECK(head); |
| 42 Persistent<MutationObserver> observer = | 42 Persistent<MutationObserver> observer = |
| 43 MutationObserver::Create(new EmptyMutationCallback(*document)); | 43 MutationObserver::Create(new EmptyMutationCallback(*document)); |
| 44 MutationObserverInit init; | 44 MutationObserverInit init; |
| 45 init.setCharacterDataOldValue(false); | 45 init.setCharacterDataOldValue(false); |
| 46 observer->observe(head, init, ASSERT_NO_EXCEPTION); | 46 observer->observe(head, init, ASSERT_NO_EXCEPTION); |
| 47 | 47 |
| 48 head->remove(); | 48 head->remove(); |
| 49 Persistent<MutationObserverRegistration> registration = | 49 Persistent<MutationObserverRegistration> registration = |
| 50 observer->registrations_.begin()->Get(); | 50 observer->registrations_.begin()->Get(); |
| 51 // The following GC will collect |head|, but won't collect a | 51 // The following GC will collect |head|, but won't collect a |
| 52 // MutationObserverRegistration for |head|. | 52 // MutationObserverRegistration for |head|. |
| 53 ThreadState::Current()->CollectGarbage(BlinkGC::kNoHeapPointersOnStack, | 53 ThreadState::Current()->CollectGarbage(BlinkGC::kNoHeapPointersOnStack, |
| 54 BlinkGC::kGCWithoutSweep, | 54 BlinkGC::kGCWithoutSweep, |
| 55 BlinkGC::kForcedGC); | 55 BlinkGC::kForcedGC); |
| 56 observer->disconnect(); | 56 observer->disconnect(); |
| 57 // The test passes if disconnect() didn't crash. crbug.com/657613. | 57 // The test passes if disconnect() didn't crash. crbug.com/657613. |
| 58 } | 58 } |
| 59 | 59 |
| 60 } // namespace blink | 60 } // namespace blink |
| OLD | NEW |