Title: [146387] trunk
Revision
146387
Author
[email protected]
Date
2013-03-20 14:13:44 -0700 (Wed, 20 Mar 2013)

Log Message

WebSpeech: Crash in WebCore::PlatformSpeechSynthesisUtterance::client / WebCore::SpeechSynthesis::didResumeSpeaking
https://bugs.webkit.org/show_bug.cgi?id=112728

Reviewed by Tim Horton.

When cancel() is called, there was a delay in the platform returning and saying speech was finished, which caused
the m_currentSpeechUtterance variable to get deallocated but not cleared. 

This patch fixes up the management of the utterances in SpeechSynthesis and the Mac platform given that
we can't rely on the platform to return immediately on a stop speaking job.

Test: platform/mac/fast/speechsynthesis/speech-synthesis-cancel-crash.html

* Modules/speech/SpeechSynthesis.cpp:
(WebCore::SpeechSynthesis::cancel):
(WebCore::SpeechSynthesis::resume):
* platform/mac/PlatformSpeechSynthesizerMac.mm:
(-[WebSpeechSynthesisWrapper cancel]):
(-[WebSpeechSynthesisWrapper speechSynthesizer:didFinishSpeaking:]):
(-[WebSpeechSynthesisWrapper speechSynthesizer:willSpeakWord:ofString:]):

Modified Paths

Added Paths

Diff

Added: trunk/LayoutTests/platform/mac/fast/speechsynthesis/speech-synthesis-cancel-crash-expected.txt (0 => 146387)


--- trunk/LayoutTests/platform/mac/fast/speechsynthesis/speech-synthesis-cancel-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/fast/speechsynthesis/speech-synthesis-cancel-crash-expected.txt	2013-03-20 21:13:44 UTC (rev 146387)
@@ -0,0 +1,9 @@
+This tests that cancelling speech at the right time will not crash due to mismanaging of the queue during a cancel.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/platform/mac/fast/speechsynthesis/speech-synthesis-cancel-crash.html (0 => 146387)


--- trunk/LayoutTests/platform/mac/fast/speechsynthesis/speech-synthesis-cancel-crash.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/fast/speechsynthesis/speech-synthesis-cancel-crash.html	2013-03-20 21:13:44 UTC (rev 146387)
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body id="body">
+
+<div id="console"></div>
+
+<script>
+
+    description("This tests that cancelling speech at the right time will not crash due to mismanaging of the queue during a cancel.");
+
+    if (window.testRunner)
+        testRunner.waitUntilDone();
+
+    if (window.internals)
+        window.internals.enableMockSpeechSynthesizer();
+
+    window.jsTestIsAsync = true;
+
+    function speak() {
+        var x = window.parent.speechSynthesis;
+        x.cancel();
+        x.resume();
+        x.speak(new SpeechSynthesisUtterance("X"));
+     }
+     speak();
+
+     // Don't crash!
+     setTimeout("speak(); finishJSTest()", 52);
+</script>
+
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (146386 => 146387)


--- trunk/Source/WebCore/ChangeLog	2013-03-20 20:55:30 UTC (rev 146386)
+++ trunk/Source/WebCore/ChangeLog	2013-03-20 21:13:44 UTC (rev 146387)
@@ -1,3 +1,26 @@
+2013-03-20  Chris Fleizach  <[email protected]>
+
+        WebSpeech: Crash in WebCore::PlatformSpeechSynthesisUtterance::client / WebCore::SpeechSynthesis::didResumeSpeaking
+        https://bugs.webkit.org/show_bug.cgi?id=112728
+
+        Reviewed by Tim Horton.
+
+        When cancel() is called, there was a delay in the platform returning and saying speech was finished, which caused
+        the m_currentSpeechUtterance variable to get deallocated but not cleared. 
+
+        This patch fixes up the management of the utterances in SpeechSynthesis and the Mac platform given that
+        we can't rely on the platform to return immediately on a stop speaking job.
+
+        Test: platform/mac/fast/speechsynthesis/speech-synthesis-cancel-crash.html
+
+        * Modules/speech/SpeechSynthesis.cpp:
+        (WebCore::SpeechSynthesis::cancel):
+        (WebCore::SpeechSynthesis::resume):
+        * platform/mac/PlatformSpeechSynthesizerMac.mm:
+        (-[WebSpeechSynthesisWrapper cancel]):
+        (-[WebSpeechSynthesisWrapper speechSynthesizer:didFinishSpeaking:]):
+        (-[WebSpeechSynthesisWrapper speechSynthesizer:willSpeakWord:ofString:]):
+
 2013-03-20  Eric Carlson  <[email protected]>
 
         Unreviewed, fix Mac release build.

Modified: trunk/Source/WebCore/Modules/speech/SpeechSynthesis.cpp (146386 => 146387)


--- trunk/Source/WebCore/Modules/speech/SpeechSynthesis.cpp	2013-03-20 20:55:30 UTC (rev 146386)
+++ trunk/Source/WebCore/Modules/speech/SpeechSynthesis.cpp	2013-03-20 21:13:44 UTC (rev 146387)
@@ -112,8 +112,14 @@
 void SpeechSynthesis::cancel()
 {
     // Remove all the items from the utterance queue.
+    // Hold on to the current utterance so the platform synthesizer can have a chance to clean up.
+    RefPtr<SpeechSynthesisUtterance> current = m_currentSpeechUtterance;
     m_utteranceQueue.clear();
     m_platformSpeechSynthesizer->cancel();
+    current = 0;
+    
+    // The platform should have called back immediately and cleared the current utterance.
+    ASSERT(!m_currentSpeechUtterance);
 }
 
 void SpeechSynthesis::pause()
@@ -124,6 +130,8 @@
 
 void SpeechSynthesis::resume()
 {
+    if (!m_currentSpeechUtterance)
+        return;
     m_platformSpeechSynthesizer->resume();
 }
 

Modified: trunk/Source/WebCore/platform/mac/PlatformSpeechSynthesizerMac.mm (146386 => 146387)


--- trunk/Source/WebCore/platform/mac/PlatformSpeechSynthesizerMac.mm	2013-03-20 20:55:30 UTC (rev 146386)
+++ trunk/Source/WebCore/platform/mac/PlatformSpeechSynthesizerMac.mm	2013-03-20 21:13:44 UTC (rev 146387)
@@ -156,12 +156,19 @@
 
 - (void)cancel
 {
+    if (!m_utterance)
+        return;
+    
     [m_synthesizer stopSpeakingAtBoundary:NSSpeechImmediateBoundary];
+    m_synthesizerObject->client()->speakingErrorOccurred(m_utterance);
+    m_utterance = 0;
 }
 
 - (void)speechSynthesizer:(NSSpeechSynthesizer *)sender didFinishSpeaking:(BOOL)finishedSpeaking
 {
-    ASSERT(m_utterance);
+    if (!m_utterance)
+        return;
+    
     UNUSED_PARAM(sender);
     
     // Clear the m_utterance variable in case finish speaking kicks off a new speaking job immediately.
@@ -176,10 +183,12 @@
 
 - (void)speechSynthesizer:(NSSpeechSynthesizer *)sender willSpeakWord:(NSRange)characterRange ofString:(NSString *)string
 {
-    ASSERT(m_utterance);
     UNUSED_PARAM(sender);
     UNUSED_PARAM(string);
 
+    if (!m_utterance)
+        return;
+
     // Mac platform only supports word boundaries.
     m_synthesizerObject->client()->boundaryEventOccurred(m_utterance, WebCore::SpeechWordBoundary, characterRange.location);
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to