[ATK] Protect entry points in the ATK wrapper against outdated render trees
authormario@webkit.org <mario@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Sep 2013 09:44:20 +0000 (09:44 +0000)
committermario@webkit.org <mario@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Sep 2013 09:44:20 +0000 (09:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=121558

Reviewed by Chris Fleizach.

Source/WebCore:

Make sure that we protect every entry point in the ATK wrapper
against outdated render trees, before using the WebCore's
accessibility API, since that might lead to problems (and crashes)
if the render and accessibility trees are not stable.

Thus, call AccessibilityObject::updateBackingStore() in those
entry points and check whether the ATK wrapper is detached or not
after that, to decide whether to continue or not.

Besides providing a new test to check that it WebKit does not
crash in a given scenario (which actually triggered the
investigation here), solving this situation also fixes other tests
that were previously failing (aria-used-on-image-maps.html) or
that were printing wrong results, not detected until now due to
wrong platform specific expectations (file-upload-button-stringvalue
and deleting-iframe-destroys-axcache).

Test: accessibility/heading-crash-after-hidden.html

* accessibility/atk/WebKitAccessibleUtil.h: Added two new macros
to inject the needed code at the beginning of each entry point to
allow gracefully exit those functions when the render tree is
unstable. Inspired by g_return_if_fail and g_return_val_if_fail, we
called them returnIfWebKitAccessibleIsInvalid and returnValIfWebKitAccessibleIsInvalid.

* accessibility/atk/WebKitAccessibleHyperlink.cpp:
(webkitAccessibleHyperlinkActionDoAction): Protect entry point.
(webkitAccessibleHyperlinkActionGetNActions): Ditto.
(webkitAccessibleHyperlinkActionGetDescription): Ditto.
(webkitAccessibleHyperlinkActionGetKeybinding): Ditto.
(webkitAccessibleHyperlinkActionGetName): Ditto.
(webkitAccessibleHyperlinkGetURI): Ditto.
(webkitAccessibleHyperlinkGetObject): Ditto.
(webkitAccessibleHyperlinkGetStartIndex): Ditto.
(webkitAccessibleHyperlinkGetEndIndex): Ditto.
(webkitAccessibleHyperlinkIsValid): Ditto.
(webkitAccessibleHyperlinkGetNAnchors): Ditto.
(webkitAccessibleHyperlinkIsSelectedLink): Ditto.
* accessibility/atk/WebKitAccessibleInterfaceAction.cpp:
(webkitAccessibleActionDoAction): Ditto.
(webkitAccessibleActionGetNActions): Ditto.
(webkitAccessibleActionGetDescription): Ditto.
(webkitAccessibleActionGetKeybinding): Ditto.
(webkitAccessibleActionGetName): Ditto.
* accessibility/atk/WebKitAccessibleInterfaceComponent.cpp:
(webkitAccessibleComponentRefAccessibleAtPoint): Ditto.
(webkitAccessibleComponentGetExtents): Ditto.
(webkitAccessibleComponentGrabFocus): Ditto.
* accessibility/atk/WebKitAccessibleInterfaceDocument.cpp:
(webkitAccessibleDocumentGetAttributeValue): Ditto.
(webkitAccessibleDocumentGetAttributes): Ditto.
(webkitAccessibleDocumentGetLocale): Ditto.
* accessibility/atk/WebKitAccessibleInterfaceEditableText.cpp:
(webkitAccessibleEditableTextSetRunAttributes): Ditto.
(webkitAccessibleEditableTextSetTextContents): Ditto.
(webkitAccessibleEditableTextInsertText): Ditto.
(webkitAccessibleEditableTextCopyText): Ditto.
(webkitAccessibleEditableTextCutText): Ditto.
(webkitAccessibleEditableTextDeleteText): Ditto.
(webkitAccessibleEditableTextPasteText): Ditto.
* accessibility/atk/WebKitAccessibleInterfaceHypertext.cpp:
(webkitAccessibleHypertextGetLink): Ditto.
(webkitAccessibleHypertextGetNLinks): Ditto.
(webkitAccessibleHypertextGetLinkIndex): Ditto.
* accessibility/atk/WebKitAccessibleInterfaceImage.cpp:
(webkitAccessibleImageGetImagePosition): Ditto.
(webkitAccessibleImageGetImageDescription): Ditto.
(webkitAccessibleImageGetImageSize): Ditto.
* accessibility/atk/WebKitAccessibleInterfaceSelection.cpp:
(webkitAccessibleSelectionAddSelection): Ditto.
(webkitAccessibleSelectionClearSelection): Ditto.
(webkitAccessibleSelectionRefSelection): Ditto.
(webkitAccessibleSelectionGetSelectionCount): Ditto.
(webkitAccessibleSelectionIsChildSelected): Ditto.
(webkitAccessibleSelectionRemoveSelection): Ditto.
(webkitAccessibleSelectionSelectAllSelection): Ditto.
* accessibility/atk/WebKitAccessibleInterfaceTable.cpp:
(webkitAccessibleTableRefAt): Ditto.
(webkitAccessibleTableGetIndexAt): Ditto.
(webkitAccessibleTableGetColumnAtIndex): Ditto.
(webkitAccessibleTableGetRowAtIndex): Ditto.
(webkitAccessibleTableGetNColumns): Ditto.
(webkitAccessibleTableGetNRows): Ditto.
(webkitAccessibleTableGetColumnExtentAt): Ditto.
(webkitAccessibleTableGetRowExtentAt): Ditto.
(webkitAccessibleTableGetColumnHeader): Ditto.
(webkitAccessibleTableGetRowHeader): Ditto.
(webkitAccessibleTableGetCaption): Ditto.
(webkitAccessibleTableGetColumnDescription): Ditto.
(webkitAccessibleTableGetRowDescription): Ditto.
* accessibility/atk/WebKitAccessibleInterfaceText.cpp:
(webkitAccessibleTextGetText): Ditto.
(webkitAccessibleTextGetTextAfterOffset): Ditto.
(webkitAccessibleTextGetTextAtOffset): Ditto.
(webkitAccessibleTextGetTextBeforeOffset): Ditto.
(webkitAccessibleTextGetCharacterAtOffset): Ditto.
(webkitAccessibleTextGetCaretOffset): Ditto.
(webkitAccessibleTextGetRunAttributes): Ditto.
(webkitAccessibleTextGetDefaultAttributes): Ditto.
(webkitAccessibleTextGetCharacterExtents): Ditto.
(webkitAccessibleTextGetRangeExtents): Ditto.
(webkitAccessibleTextGetCharacterCount): Ditto.
(webkitAccessibleTextGetOffsetAtPoint): Ditto.
(webkitAccessibleTextGetNSelections): Ditto.
(webkitAccessibleTextGetSelection): Ditto.
(webkitAccessibleTextAddSelection): Ditto.
(webkitAccessibleTextSetSelection): Ditto.
(webkitAccessibleTextRemoveSelection): Ditto.
(webkitAccessibleTextSetCaretOffset): Ditto.
* accessibility/atk/WebKitAccessibleInterfaceValue.cpp:
(webkitAccessibleValueGetCurrentValue): Ditto.
(webkitAccessibleValueGetMaximumValue): Ditto.
(webkitAccessibleValueGetMinimumValue): Ditto.
(webkitAccessibleValueSetCurrentValue): Ditto.
(webkitAccessibleValueGetMinimumIncrement): Ditto.
* accessibility/atk/WebKitAccessibleWrapperAtk.cpp:
(core): Removed, as it's not actually needed.
(webkitAccessibleGetName):  Protect entry point.
(webkitAccessibleGetDescription): Ditto.
(webkitAccessibleGetParent): Ditto.
(webkitAccessibleGetNChildren): Ditto.
(webkitAccessibleRefChild): Ditto.
(webkitAccessibleGetIndexInParent): Ditto.
(webkitAccessibleGetAttributes): Ditto.
(webkitAccessibleGetRole): Ditto.
(webkitAccessibleRefStateSet): Ditto.
(webkitAccessibleRefRelationSet): Ditto.
(webkitAccessibleGetObjectLocale): Ditto.
(webkitAccessibleDetach): Ditto.
(webkitAccessibleIsDetached): New helper function, to be used from
the newly added macros. We need to check whether the wrapper is
detached and not just the wrapper AccessibilityObject since once
the detachment happens we can't trust anything but the AtkObject
from the wrapper (the AccessibilityObject might be invalid).
* accessibility/atk/WebKitAccessibleWrapperAtk.h:

Assert that the render tree is neither being updated nor in need
of being updated before trying to compute the text under a given
element, since that might lead to crashes due to the constructor
of TextIterator calling updateLayoutIgnorePendingStylesheets().

* accessibility/AccessibilityNodeObject.cpp:
(WebCore::AccessibilityNodeObject::textUnderElement): Assert that
the render tree is neither being updated nor needing updating.

LayoutTests:

Added a new test to check that we do not crash in certain
scenarios when hiding objects and retriving accessibility
information about it.

* accessibility/heading-crash-after-hidden-expected.txt: Added.
* accessibility/heading-crash-after-hidden.html: Added.

Rebaselined expectations that were wrong before, since they were
not returning the actual value that they should be returning when
called AccessibilityUIElement::stringValue().

* platform/efl-wk1/accessibility/file-upload-button-stringvalue-expected.txt:
Updated, since the actual text being returned should be the actual
value of the file chooser (e.g. "(None)") and not the text in the
upload botton (e.g. "Choose files").
* platform/efl-wk2/accessibility/file-upload-button-stringvalue-expected.txt: Ditto.
* platform/gtk-wk2/accessibility/file-upload-button-stringvalue-expected.txt: Ditto..
* platform/gtk/accessibility/file-upload-button-stringvalue-expected.txt: Ditto.

* platform/gtk/accessibility/deleting-iframe-destroys-axcache-expected.txt:
Updated, since the iframe should be exposed at all after deleting it.

Removed accesibility test now passing after fixing this issue.

* platform/gtk/TestExpectations: Removed accessibility/aria-used-on-image-maps.html.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@156532 268f45cc-cd09-0410-ab3c-d52691b4dbfc

25 files changed:
LayoutTests/ChangeLog
LayoutTests/accessibility/heading-crash-after-hidden-expected.txt [new file with mode: 0644]
LayoutTests/accessibility/heading-crash-after-hidden.html [new file with mode: 0644]
LayoutTests/platform/efl-wk1/accessibility/file-upload-button-stringvalue-expected.txt
LayoutTests/platform/efl-wk2/accessibility/file-upload-button-stringvalue-expected.txt
LayoutTests/platform/gtk-wk2/accessibility/file-upload-button-stringvalue-expected.txt
LayoutTests/platform/gtk/TestExpectations
LayoutTests/platform/gtk/accessibility/deleting-iframe-destroys-axcache-expected.txt
LayoutTests/platform/gtk/accessibility/file-upload-button-stringvalue-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityNodeObject.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleHyperlink.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceAction.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceComponent.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceDocument.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceEditableText.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceHypertext.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceImage.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceSelection.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceTable.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceValue.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleUtil.h
Source/WebCore/accessibility/atk/WebKitAccessibleWrapperAtk.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleWrapperAtk.h

index 8028084..864e874 100644 (file)
@@ -1,3 +1,36 @@
+2013-09-27  Mario Sanchez Prada  <mario.prada@samsung.com>
+
+        [ATK] Protect entry points in the ATK wrapper against outdated render trees
+        https://bugs.webkit.org/show_bug.cgi?id=121558
+
+        Reviewed by Chris Fleizach.
+
+        Added a new test to check that we do not crash in certain
+        scenarios when hiding objects and retriving accessibility
+        information about it.
+
+        * accessibility/heading-crash-after-hidden-expected.txt: Added.
+        * accessibility/heading-crash-after-hidden.html: Added.
+
+        Rebaselined expectations that were wrong before, since they were
+        not returning the actual value that they should be returning when
+        called AccessibilityUIElement::stringValue().
+
+        * platform/efl-wk1/accessibility/file-upload-button-stringvalue-expected.txt:
+        Updated, since the actual text being returned should be the actual
+        value of the file chooser (e.g. "(None)") and not the text in the
+        upload botton (e.g. "Choose files").
+        * platform/efl-wk2/accessibility/file-upload-button-stringvalue-expected.txt: Ditto.
+        * platform/gtk-wk2/accessibility/file-upload-button-stringvalue-expected.txt: Ditto..
+        * platform/gtk/accessibility/file-upload-button-stringvalue-expected.txt: Ditto.
+
+        * platform/gtk/accessibility/deleting-iframe-destroys-axcache-expected.txt:
+        Updated, since the iframe should be exposed at all after deleting it.
+
+        Removed accesibility test now passing after fixing this issue.
+
+        * platform/gtk/TestExpectations: Removed accessibility/aria-used-on-image-maps.html.
+
 2013-09-26  Antti Koivisto  <antti@apple.com>
 
         Move m_style to RenderElement
diff --git a/LayoutTests/accessibility/heading-crash-after-hidden-expected.txt b/LayoutTests/accessibility/heading-crash-after-hidden-expected.txt
new file mode 100644 (file)
index 0000000..38b434f
--- /dev/null
@@ -0,0 +1,11 @@
+This tests that we don't get a crash when trying to retrieve textual information for a heading after hiding it.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+AXTitle: X
+AXRole: AXHeading
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/accessibility/heading-crash-after-hidden.html b/LayoutTests/accessibility/heading-crash-after-hidden.html
new file mode 100644 (file)
index 0000000..52ca0b5
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<script src="../resources/js-test-pre.js"></script>
+
+<h1 id="heading">X</h1>
+
+<div id="console"></div>
+<script>
+if (window.testRunner && window.accessibilityController) {
+    description("This tests that we don't get a crash when trying to retrieve textual information for a heading after hiding it.");
+    var heading = document.getElementById("heading");
+    var axHeading = accessibilityController.rootElement.childAtIndex(0).childAtIndex(0);
+    debug(axHeading.title);
+    debug(axHeading.role);
+
+    // Hide the heading now.
+    heading.style.display = 'none';
+
+    // Forcing a retrieval of text associated to the object
+    // should not crash after hiding the heading.
+    axHeading.title;
+    axHeading.description;
+}
+</script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
\ No newline at end of file
index 0d1c11c..4a5de2d 100644 (file)
@@ -3,8 +3,8 @@ This tests the value of stringValue for a single file- and multiple files-<input
 
 
 Default value (no files selected):
-accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: Choose File
-accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: Choose Files
+accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: (None)
+accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: (None)
 
 Drag and drop a single file:
 accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: file1.txt
index 6017168..ce7dcf0 100644 (file)
@@ -3,14 +3,14 @@ This tests the value of stringValue for a single file- and multiple files-<input
 
 
 Default value (no files selected):
-accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: Choose File
-accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: Choose Files
+accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: (None)
+accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: (None)
 
 Drag and drop a single file:
-accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: Choose File
-accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: Choose Files
+accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: (None)
+accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: (None)
 
 Drag and drop two files:
-accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: Choose File
-accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: Choose Files
+accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: (None)
+accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: (None)
 
index 6017168..ce7dcf0 100644 (file)
@@ -3,14 +3,14 @@ This tests the value of stringValue for a single file- and multiple files-<input
 
 
 Default value (no files selected):
-accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: Choose File
-accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: Choose Files
+accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: (None)
+accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: (None)
 
 Drag and drop a single file:
-accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: Choose File
-accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: Choose Files
+accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: (None)
+accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: (None)
 
 Drag and drop two files:
-accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: Choose File
-accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: Choose Files
+accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: (None)
+accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: (None)
 
index 7c610a1..c9a36ff 100644 (file)
@@ -849,7 +849,6 @@ webkit.org/b/121684 accessibility/aria-describedby-on-input.html [ Failure ]
 webkit.org/b/98355 accessibility/aria-link-supports-press.html [ Failure ]
 webkit.org/b/98357 accessibility/aria-readonly.html [ Failure ]
 webkit.org/b/98359 accessibility/aria-text-role.html [ Failure ]
-webkit.org/b/98360 accessibility/aria-used-on-image-maps.html [ Failure ]
 webkit.org/b/98361 accessibility/button-press-action.html [ Failure ]
 webkit.org/b/98363 accessibility/canvas-fallback-content-2.html [ Failure ]
 webkit.org/b/98371 accessibility/loading-iframe-updates-axtree.html [ Failure ]
index 742abe1..0fee235 100644 (file)
@@ -26,7 +26,6 @@ After:
 AXRole: AXScrollArea 
     AXRole: AXWebArea 
         AXRole: AXParagraph AXValue: Before
-        AXRole: AXGroup AXValue: 
         AXRole: AXParagraph AXValue: After
         AXRole: AXParagraph AXValue: End of test
 
index 0d1c11c..4a5de2d 100644 (file)
@@ -3,8 +3,8 @@ This tests the value of stringValue for a single file- and multiple files-<input
 
 
 Default value (no files selected):
-accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: Choose File
-accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: Choose Files
+accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: (None)
+accessibilityController.accessibleElementById("multipleFileUpload").stringValue: AXValue: (None)
 
 Drag and drop a single file:
 accessibilityController.accessibleElementById("singleFileUpload").stringValue: AXValue: file1.txt
index dc33f88..a752ae6 100644 (file)
@@ -1,5 +1,157 @@
 2013-09-27  Mario Sanchez Prada  <mario.prada@samsung.com>
 
+        [ATK] Protect entry points in the ATK wrapper against outdated render trees
+        https://bugs.webkit.org/show_bug.cgi?id=121558
+
+        Reviewed by Chris Fleizach.
+
+        Make sure that we protect every entry point in the ATK wrapper
+        against outdated render trees, before using the WebCore's
+        accessibility API, since that might lead to problems (and crashes)
+        if the render and accessibility trees are not stable.
+
+        Thus, call AccessibilityObject::updateBackingStore() in those
+        entry points and check whether the ATK wrapper is detached or not
+        after that, to decide whether to continue or not.
+
+        Besides providing a new test to check that it WebKit does not
+        crash in a given scenario (which actually triggered the
+        investigation here), solving this situation also fixes other tests
+        that were previously failing (aria-used-on-image-maps.html) or
+        that were printing wrong results, not detected until now due to
+        wrong platform specific expectations (file-upload-button-stringvalue
+        and deleting-iframe-destroys-axcache).
+
+        Test: accessibility/heading-crash-after-hidden.html
+
+        * accessibility/atk/WebKitAccessibleUtil.h: Added two new macros
+        to inject the needed code at the beginning of each entry point to
+        allow gracefully exit those functions when the render tree is
+        unstable. Inspired by g_return_if_fail and g_return_val_if_fail, we
+        called them returnIfWebKitAccessibleIsInvalid and returnValIfWebKitAccessibleIsInvalid.
+
+        * accessibility/atk/WebKitAccessibleHyperlink.cpp:
+        (webkitAccessibleHyperlinkActionDoAction): Protect entry point.
+        (webkitAccessibleHyperlinkActionGetNActions): Ditto.
+        (webkitAccessibleHyperlinkActionGetDescription): Ditto.
+        (webkitAccessibleHyperlinkActionGetKeybinding): Ditto.
+        (webkitAccessibleHyperlinkActionGetName): Ditto.
+        (webkitAccessibleHyperlinkGetURI): Ditto.
+        (webkitAccessibleHyperlinkGetObject): Ditto.
+        (webkitAccessibleHyperlinkGetStartIndex): Ditto.
+        (webkitAccessibleHyperlinkGetEndIndex): Ditto.
+        (webkitAccessibleHyperlinkIsValid): Ditto.
+        (webkitAccessibleHyperlinkGetNAnchors): Ditto.
+        (webkitAccessibleHyperlinkIsSelectedLink): Ditto.
+        * accessibility/atk/WebKitAccessibleInterfaceAction.cpp:
+        (webkitAccessibleActionDoAction): Ditto.
+        (webkitAccessibleActionGetNActions): Ditto.
+        (webkitAccessibleActionGetDescription): Ditto.
+        (webkitAccessibleActionGetKeybinding): Ditto.
+        (webkitAccessibleActionGetName): Ditto.
+        * accessibility/atk/WebKitAccessibleInterfaceComponent.cpp:
+        (webkitAccessibleComponentRefAccessibleAtPoint): Ditto.
+        (webkitAccessibleComponentGetExtents): Ditto.
+        (webkitAccessibleComponentGrabFocus): Ditto.
+        * accessibility/atk/WebKitAccessibleInterfaceDocument.cpp:
+        (webkitAccessibleDocumentGetAttributeValue): Ditto.
+        (webkitAccessibleDocumentGetAttributes): Ditto.
+        (webkitAccessibleDocumentGetLocale): Ditto.
+        * accessibility/atk/WebKitAccessibleInterfaceEditableText.cpp:
+        (webkitAccessibleEditableTextSetRunAttributes): Ditto.
+        (webkitAccessibleEditableTextSetTextContents): Ditto.
+        (webkitAccessibleEditableTextInsertText): Ditto.
+        (webkitAccessibleEditableTextCopyText): Ditto.
+        (webkitAccessibleEditableTextCutText): Ditto.
+        (webkitAccessibleEditableTextDeleteText): Ditto.
+        (webkitAccessibleEditableTextPasteText): Ditto.
+        * accessibility/atk/WebKitAccessibleInterfaceHypertext.cpp:
+        (webkitAccessibleHypertextGetLink): Ditto.
+        (webkitAccessibleHypertextGetNLinks): Ditto.
+        (webkitAccessibleHypertextGetLinkIndex): Ditto.
+        * accessibility/atk/WebKitAccessibleInterfaceImage.cpp:
+        (webkitAccessibleImageGetImagePosition): Ditto.
+        (webkitAccessibleImageGetImageDescription): Ditto.
+        (webkitAccessibleImageGetImageSize): Ditto.
+        * accessibility/atk/WebKitAccessibleInterfaceSelection.cpp:
+        (webkitAccessibleSelectionAddSelection): Ditto.
+        (webkitAccessibleSelectionClearSelection): Ditto.
+        (webkitAccessibleSelectionRefSelection): Ditto.
+        (webkitAccessibleSelectionGetSelectionCount): Ditto.
+        (webkitAccessibleSelectionIsChildSelected): Ditto.
+        (webkitAccessibleSelectionRemoveSelection): Ditto.
+        (webkitAccessibleSelectionSelectAllSelection): Ditto.
+        * accessibility/atk/WebKitAccessibleInterfaceTable.cpp:
+        (webkitAccessibleTableRefAt): Ditto.
+        (webkitAccessibleTableGetIndexAt): Ditto.
+        (webkitAccessibleTableGetColumnAtIndex): Ditto.
+        (webkitAccessibleTableGetRowAtIndex): Ditto.
+        (webkitAccessibleTableGetNColumns): Ditto.
+        (webkitAccessibleTableGetNRows): Ditto.
+        (webkitAccessibleTableGetColumnExtentAt): Ditto.
+        (webkitAccessibleTableGetRowExtentAt): Ditto.
+        (webkitAccessibleTableGetColumnHeader): Ditto.
+        (webkitAccessibleTableGetRowHeader): Ditto.
+        (webkitAccessibleTableGetCaption): Ditto.
+        (webkitAccessibleTableGetColumnDescription): Ditto.
+        (webkitAccessibleTableGetRowDescription): Ditto.
+        * accessibility/atk/WebKitAccessibleInterfaceText.cpp:
+        (webkitAccessibleTextGetText): Ditto.
+        (webkitAccessibleTextGetTextAfterOffset): Ditto.
+        (webkitAccessibleTextGetTextAtOffset): Ditto.
+        (webkitAccessibleTextGetTextBeforeOffset): Ditto.
+        (webkitAccessibleTextGetCharacterAtOffset): Ditto.
+        (webkitAccessibleTextGetCaretOffset): Ditto.
+        (webkitAccessibleTextGetRunAttributes): Ditto.
+        (webkitAccessibleTextGetDefaultAttributes): Ditto.
+        (webkitAccessibleTextGetCharacterExtents): Ditto.
+        (webkitAccessibleTextGetRangeExtents): Ditto.
+        (webkitAccessibleTextGetCharacterCount): Ditto.
+        (webkitAccessibleTextGetOffsetAtPoint): Ditto.
+        (webkitAccessibleTextGetNSelections): Ditto.
+        (webkitAccessibleTextGetSelection): Ditto.
+        (webkitAccessibleTextAddSelection): Ditto.
+        (webkitAccessibleTextSetSelection): Ditto.
+        (webkitAccessibleTextRemoveSelection): Ditto.
+        (webkitAccessibleTextSetCaretOffset): Ditto.
+        * accessibility/atk/WebKitAccessibleInterfaceValue.cpp:
+        (webkitAccessibleValueGetCurrentValue): Ditto.
+        (webkitAccessibleValueGetMaximumValue): Ditto.
+        (webkitAccessibleValueGetMinimumValue): Ditto.
+        (webkitAccessibleValueSetCurrentValue): Ditto.
+        (webkitAccessibleValueGetMinimumIncrement): Ditto.
+        * accessibility/atk/WebKitAccessibleWrapperAtk.cpp:
+        (core): Removed, as it's not actually needed.
+        (webkitAccessibleGetName):  Protect entry point.
+        (webkitAccessibleGetDescription): Ditto.
+        (webkitAccessibleGetParent): Ditto.
+        (webkitAccessibleGetNChildren): Ditto.
+        (webkitAccessibleRefChild): Ditto.
+        (webkitAccessibleGetIndexInParent): Ditto.
+        (webkitAccessibleGetAttributes): Ditto.
+        (webkitAccessibleGetRole): Ditto.
+        (webkitAccessibleRefStateSet): Ditto.
+        (webkitAccessibleRefRelationSet): Ditto.
+        (webkitAccessibleGetObjectLocale): Ditto.
+        (webkitAccessibleDetach): Ditto.
+        (webkitAccessibleIsDetached): New helper function, to be used from
+        the newly added macros. We need to check whether the wrapper is
+        detached and not just the wrapper AccessibilityObject since once
+        the detachment happens we can't trust anything but the AtkObject
+        from the wrapper (the AccessibilityObject might be invalid).
+        * accessibility/atk/WebKitAccessibleWrapperAtk.h:
+
+        Assert that the render tree is neither being updated nor in need
+        of being updated before trying to compute the text under a given
+        element, since that might lead to crashes due to the constructor
+        of TextIterator calling updateLayoutIgnorePendingStylesheets().
+
+        * accessibility/AccessibilityNodeObject.cpp:
+        (WebCore::AccessibilityNodeObject::textUnderElement): Assert that
+        the render tree is neither being updated nor needing updating.
+
+2013-09-27  Mario Sanchez Prada  <mario.prada@samsung.com>
+
         [ATK] accessibility/aria-sort.html is failing after r156409
         https://bugs.webkit.org/show_bug.cgi?id=121947
 
index cdcffdd..d7bf68a 100644 (file)
@@ -68,6 +68,7 @@
 #include "NodeTraversal.h"
 #include "Page.h"
 #include "ProgressTracker.h"
+#include "RenderView.h"
 #include "SVGElement.h"
 #include "SVGNames.h"
 #include "Text.h"
@@ -1580,6 +1581,12 @@ String AccessibilityNodeObject::textUnderElement(AccessibilityTextUnderElementMo
     if (node && node->isTextNode())
         return toText(node)->wholeText();
 
+    // The render tree should be stable before going ahead. Otherwise, further uses of the
+    // TextIterator will force a layout update, potentially altering the accessibility tree
+    // and leading to crashes in the loop that computes the result text from the children.
+    ASSERT(!document()->renderView()->layoutState());
+    ASSERT(!document()->childNeedsStyleRecalc());
+
     StringBuilder builder;
     for (AccessibilityObject* child = firstChild(); child; child = child->nextSibling()) {
         if (!shouldUseAccessiblityObjectInnerText(child, mode))
index fe34577..57258cb 100644 (file)
@@ -94,6 +94,7 @@ static gboolean webkitAccessibleHyperlinkActionDoAction(AtkAction* action, gint
     g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), FALSE);
     g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, FALSE);
     g_return_val_if_fail(!index, FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, FALSE);
 
     if (!ATK_IS_ACTION(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl))
         return FALSE;
@@ -109,6 +110,7 @@ static gint webkitAccessibleHyperlinkActionGetNActions(AtkAction* action)
 {
     g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0);
     g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, 0);
 
     if (!ATK_IS_ACTION(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl))
         return 0;
@@ -121,6 +123,7 @@ static const gchar* webkitAccessibleHyperlinkActionGetDescription(AtkAction* act
     g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0);
     g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, 0);
     g_return_val_if_fail(!index, 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, 0);
 
     // TODO: Need a way to provide/localize action descriptions.
     notImplemented();
@@ -130,10 +133,11 @@ static const gchar* webkitAccessibleHyperlinkActionGetDescription(AtkAction* act
 static const gchar* webkitAccessibleHyperlinkActionGetKeybinding(AtkAction* action, gint index)
 {
     g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0);
+    g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, 0);
     g_return_val_if_fail(!index, 0);
 
     WebKitAccessibleHyperlinkPrivate* priv = WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv;
-    g_return_val_if_fail(priv->hyperlinkImpl, 0);
+    returnValIfWebKitAccessibleIsInvalid(priv->hyperlinkImpl, 0);
 
     if (!ATK_IS_ACTION(priv->hyperlinkImpl))
         return 0;
@@ -149,10 +153,11 @@ static const gchar* webkitAccessibleHyperlinkActionGetKeybinding(AtkAction* acti
 static const gchar* webkitAccessibleHyperlinkActionGetName(AtkAction* action, gint index)
 {
     g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0);
+    g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, 0);
     g_return_val_if_fail(!index, 0);
 
     WebKitAccessibleHyperlinkPrivate* priv = WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv;
-    g_return_val_if_fail(priv->hyperlinkImpl, 0);
+    returnValIfWebKitAccessibleIsInvalid(priv->hyperlinkImpl, 0);
 
     if (!ATK_IS_ACTION(priv->hyperlinkImpl))
         return 0;
@@ -177,10 +182,14 @@ static void atkActionInterfaceInit(AtkActionIface* iface)
 static gchar* webkitAccessibleHyperlinkGetURI(AtkHyperlink* link, gint index)
 {
     g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
+    g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0);
+
     // FIXME: Do NOT support more than one instance of an AtkObject
     // implementing AtkHyperlinkImpl in every instance of AtkHyperLink
     g_return_val_if_fail(!index, 0);
 
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0);
+
     AccessibilityObject* coreObject = core(link);
     if (!coreObject || coreObject->url().isNull())
         return 0;
@@ -197,6 +206,8 @@ static AtkObject* webkitAccessibleHyperlinkGetObject(AtkHyperlink* link, gint in
     // implementing AtkHyperlinkImpl in every instance of AtkHyperLink
     g_return_val_if_fail(!index, 0);
 
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0);
+
     return ATK_OBJECT(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl);
 }
 
@@ -230,6 +241,8 @@ static gint getRangeLengthForObject(AccessibilityObject* obj, Range* range)
 static gint webkitAccessibleHyperlinkGetStartIndex(AtkHyperlink* link)
 {
     g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
+    g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0);
 
     AccessibilityObject* coreObject = core(link);
     if (!coreObject)
@@ -254,6 +267,8 @@ static gint webkitAccessibleHyperlinkGetStartIndex(AtkHyperlink* link)
 static gint webkitAccessibleHyperlinkGetEndIndex(AtkHyperlink* link)
 {
     g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
+    g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0);
 
     AccessibilityObject* coreObject = core(link);
     if (!coreObject)
@@ -277,8 +292,9 @@ static gint webkitAccessibleHyperlinkGetEndIndex(AtkHyperlink* link)
 
 static gboolean webkitAccessibleHyperlinkIsValid(AtkHyperlink* link)
 {
-    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), FALSE);
     g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, FALSE);
 
     // Link is valid for the whole object's lifetime
     return TRUE;
@@ -290,11 +306,17 @@ static gint webkitAccessibleHyperlinkGetNAnchors(AtkHyperlink* link)
     // implementing AtkHyperlinkImpl in every instance of AtkHyperLink
     g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
     g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0);
+
     return 1;
 }
 
-static gboolean webkitAccessibleHyperlinkIsSelectedLink(AtkHyperlink*)
+static gboolean webkitAccessibleHyperlinkIsSelectedLink(AtkHyperlink* link)
 {
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), FALSE);
+    g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, FALSE);
+
     // Not implemented: this function is deprecated in ATK now
     notImplemented();
     return FALSE;
index eb18beb..c79bdc4 100644 (file)
@@ -51,17 +51,27 @@ static AccessibilityObject* core(AtkAction* action)
 
 static gboolean webkitAccessibleActionDoAction(AtkAction* action, gint index)
 {
+    g_return_val_if_fail(ATK_IS_ACTION(action), FALSE);
     g_return_val_if_fail(!index, FALSE);
+
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(action), FALSE);
+
     return core(action)->performDefaultAction();
 }
 
-static gint webkitAccessibleActionGetNActions(AtkAction*)
+static gint webkitAccessibleActionGetNActions(AtkAction* action)
 {
+    g_return_val_if_fail(ATK_IS_ACTION(action), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(action), 0);
+
     return 1;
 }
 
-static const gchar* webkitAccessibleActionGetDescription(AtkAction*, gint)
+static const gchar* webkitAccessibleActionGetDescription(AtkAction* action, gint)
 {
+    g_return_val_if_fail(ATK_IS_ACTION(action), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(action), 0);
+
     // TODO: Need a way to provide/localize action descriptions.
     notImplemented();
     return "";
@@ -69,14 +79,20 @@ static const gchar* webkitAccessibleActionGetDescription(AtkAction*, gint)
 
 static const gchar* webkitAccessibleActionGetKeybinding(AtkAction* action, gint index)
 {
+    g_return_val_if_fail(ATK_IS_ACTION(action), 0);
     g_return_val_if_fail(!index, 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(action), 0);
+
     // FIXME: Construct a proper keybinding string.
     return cacheAndReturnAtkProperty(ATK_OBJECT(action), AtkCachedActionKeyBinding, core(action)->accessKey().string());
 }
 
 static const gchar* webkitAccessibleActionGetName(AtkAction* action, gint index)
 {
+    g_return_val_if_fail(ATK_IS_ACTION(action), 0);
     g_return_val_if_fail(!index, 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(action), 0);
+
     return cacheAndReturnAtkProperty(ATK_OBJECT(action), AtkCachedActionName, core(action)->actionVerb());
 }
 
index 7103ea6..b93d8c3 100644 (file)
@@ -68,6 +68,9 @@ static IntPoint atkToContents(AccessibilityObject* coreObject, AtkCoordType coor
 
 static AtkObject* webkitAccessibleComponentRefAccessibleAtPoint(AtkComponent* component, gint x, gint y, AtkCoordType coordType)
 {
+    g_return_val_if_fail(ATK_IS_COMPONENT(component), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(component), 0);
+
     IntPoint pos = atkToContents(core(component), coordType, x, y);
 
     AccessibilityObject* target = core(component)->accessibilityHitTest(pos);
@@ -79,12 +82,18 @@ static AtkObject* webkitAccessibleComponentRefAccessibleAtPoint(AtkComponent* co
 
 static void webkitAccessibleComponentGetExtents(AtkComponent* component, gint* x, gint* y, gint* width, gint* height, AtkCoordType coordType)
 {
+    g_return_if_fail(ATK_IS_COMPONENT(component));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(component));
+
     IntRect rect = pixelSnappedIntRect(core(component)->elementRect());
     contentsRelativeToAtkCoordinateType(core(component), coordType, rect, x, y, width, height);
 }
 
 static gboolean webkitAccessibleComponentGrabFocus(AtkComponent* component)
 {
+    g_return_val_if_fail(ATK_IS_COMPONENT(component), FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(component), FALSE);
+
     core(component)->setFocused(true);
     return core(component)->isFocused();
 }
index f074843..5a52f81 100644 (file)
@@ -78,11 +78,17 @@ static const gchar* documentAttributeValue(AtkDocument* document, const gchar* a
 
 static const gchar* webkitAccessibleDocumentGetAttributeValue(AtkDocument* document, const gchar* attribute)
 {
+    g_return_val_if_fail(ATK_IS_DOCUMENT(document), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(document), 0);
+
     return documentAttributeValue(document, attribute);
 }
 
 static AtkAttributeSet* webkitAccessibleDocumentGetAttributes(AtkDocument* document)
 {
+    g_return_val_if_fail(ATK_IS_DOCUMENT(document), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(document), 0);
+
     AtkAttributeSet* attributeSet = 0;
     const gchar* attributes[] = { "DocType", "Encoding", "URI" };
 
@@ -97,6 +103,9 @@ static AtkAttributeSet* webkitAccessibleDocumentGetAttributes(AtkDocument* docum
 
 static const gchar* webkitAccessibleDocumentGetLocale(AtkDocument* document)
 {
+    g_return_val_if_fail(ATK_IS_DOCUMENT(document), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(document), 0);
+
     // The logic to resolve locale has been moved to
     // AtkObject::get_object_locale() virtual method. However, to avoid breaking
     // clients expecting the deprecated AtkDocumentIface::get_document_locale()
index a33c593..a12e96a 100644 (file)
@@ -38,6 +38,7 @@
 #include "Editor.h"
 #include "Frame.h"
 #include "NotImplemented.h"
+#include "WebKitAccessibleUtil.h"
 #include "WebKitAccessibleWrapperAtk.h"
 
 using namespace WebCore;
@@ -50,20 +51,29 @@ static AccessibilityObject* core(AtkEditableText* text)
     return webkitAccessibleGetAccessibilityObject(WEBKIT_ACCESSIBLE(text));
 }
 
-static gboolean webkitAccessibleEditableTextSetRunAttributes(AtkEditableText*, AtkAttributeSet*, gint, gint)
+static gboolean webkitAccessibleEditableTextSetRunAttributes(AtkEditableText* text, AtkAttributeSet*, gint, gint)
 {
+    g_return_val_if_fail(ATK_IS_EDITABLE_TEXT(text), FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), FALSE);
+
     notImplemented();
     return FALSE;
 }
 
 static void webkitAccessibleEditableTextSetTextContents(AtkEditableText* text, const gchar* string)
 {
+    g_return_if_fail(ATK_IS_EDITABLE_TEXT(text));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text));
+
     // FIXME: string nullcheck?
     core(text)->setValue(String::fromUTF8(string));
 }
 
 static void webkitAccessibleEditableTextInsertText(AtkEditableText* text, const gchar* string, gint length, gint* position)
 {
+    g_return_if_fail(ATK_IS_EDITABLE_TEXT(text));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text));
+
     if (!string)
         return;
 
@@ -83,18 +93,27 @@ static void webkitAccessibleEditableTextInsertText(AtkEditableText* text, const
         *position += length;
 }
 
-static void webkitAccessibleEditableTextCopyText(AtkEditableText*, gint, gint)
+static void webkitAccessibleEditableTextCopyText(AtkEditableText* text, gint, gint)
 {
+    g_return_if_fail(ATK_IS_EDITABLE_TEXT(text));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text));
+
     notImplemented();
 }
 
-static void webkitAccessibleEditableTextCutText(AtkEditableText*, gint, gint)
+static void webkitAccessibleEditableTextCutText(AtkEditableText* text, gint, gint)
 {
+    g_return_if_fail(ATK_IS_EDITABLE_TEXT(text));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text));
+
     notImplemented();
 }
 
 static void webkitAccessibleEditableTextDeleteText(AtkEditableText* text, gint startPos, gint endPos)
 {
+    g_return_if_fail(ATK_IS_EDITABLE_TEXT(text));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text));
+
     AccessibilityObject* coreObject = core(text);
     // FIXME: Not implemented in WebCore
     // coreObject->setSelectedTextRange(PlainTextRange(startPos, endPos - startPos));
@@ -109,8 +128,11 @@ static void webkitAccessibleEditableTextDeleteText(AtkEditableText* text, gint s
     document->frame()->editor().performDelete();
 }
 
-static void webkitAccessibleEditableTextPasteText(AtkEditableText*, gint)
+static void webkitAccessibleEditableTextPasteText(AtkEditableText* text, gint)
 {
+    g_return_if_fail(ATK_IS_EDITABLE_TEXT(text));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text));
+
     notImplemented();
 }
 
index 0e338d8..671b4aa 100644 (file)
@@ -23,6 +23,7 @@
 #if HAVE(ACCESSIBILITY)
 
 #include "AccessibilityObject.h"
+#include "WebKitAccessibleUtil.h"
 #include "WebKitAccessibleWrapperAtk.h"
 
 using namespace WebCore;
@@ -37,6 +38,9 @@ static AccessibilityObject* core(AtkHypertext* hypertext)
 
 static AtkHyperlink* webkitAccessibleHypertextGetLink(AtkHypertext* hypertext, gint index)
 {
+    g_return_val_if_fail(ATK_HYPERTEXT(hypertext), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(hypertext), 0);
+
     AccessibilityObject::AccessibilityChildrenVector children = core(hypertext)->children();
     if (index < 0 || static_cast<unsigned>(index) >= children.size())
         return 0;
@@ -62,6 +66,9 @@ static AtkHyperlink* webkitAccessibleHypertextGetLink(AtkHypertext* hypertext, g
 
 static gint webkitAccessibleHypertextGetNLinks(AtkHypertext* hypertext)
 {
+    g_return_val_if_fail(ATK_HYPERTEXT(hypertext), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(hypertext), 0);
+
     AccessibilityObject::AccessibilityChildrenVector children = core(hypertext)->children();
     if (!children.size())
         return 0;
@@ -81,6 +88,9 @@ static gint webkitAccessibleHypertextGetNLinks(AtkHypertext* hypertext)
 
 static gint webkitAccessibleHypertextGetLinkIndex(AtkHypertext* hypertext, gint charIndex)
 {
+    g_return_val_if_fail(ATK_HYPERTEXT(hypertext), -1);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(hypertext), -1);
+
     size_t linksCount = webkitAccessibleHypertextGetNLinks(hypertext);
     if (!linksCount)
         return -1;
index 6d7df12..bab7599 100644 (file)
@@ -51,17 +51,26 @@ static AccessibilityObject* core(AtkImage* image)
 
 static void webkitAccessibleImageGetImagePosition(AtkImage* image, gint* x, gint* y, AtkCoordType coordType)
 {
+    g_return_if_fail(ATK_IMAGE(image));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(image));
+
     IntRect rect = pixelSnappedIntRect(core(image)->elementRect());
     contentsRelativeToAtkCoordinateType(core(image), coordType, rect, x, y);
 }
 
 static const gchar* webkitAccessibleImageGetImageDescription(AtkImage* image)
 {
+    g_return_val_if_fail(ATK_IMAGE(image), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(image), 0);
+
     return cacheAndReturnAtkProperty(ATK_OBJECT(image), AtkCachedImageDescription, accessibilityDescription(core(image)));
 }
 
 static void webkitAccessibleImageGetImageSize(AtkImage* image, gint* width, gint* height)
 {
+    g_return_if_fail(ATK_IMAGE(image));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(image));
+
     IntSize size = core(image)->pixelSnappedSize();
 
     if (width)
index 7e024b0..c1d3a11 100644 (file)
@@ -37,6 +37,7 @@
 #include "AccessibilityObject.h"
 #include "HTMLSelectElement.h"
 #include "RenderObject.h"
+#include "WebKitAccessibleUtil.h"
 #include "WebKitAccessibleWrapperAtk.h"
 
 using namespace WebCore;
@@ -127,6 +128,9 @@ static AccessibilityObject* optionFromSelection(AtkSelection* selection, gint in
 
 static gboolean webkitAccessibleSelectionAddSelection(AtkSelection* selection, gint index)
 {
+    g_return_val_if_fail(ATK_SELECTION(selection), FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(selection), FALSE);
+
     AccessibilityObject* coreSelection = core(selection);
     if (!coreSelection)
         return FALSE;
@@ -142,6 +146,9 @@ static gboolean webkitAccessibleSelectionAddSelection(AtkSelection* selection, g
 
 static gboolean webkitAccessibleSelectionClearSelection(AtkSelection* selection)
 {
+    g_return_val_if_fail(ATK_SELECTION(selection), FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(selection), FALSE);
+
     AccessibilityObject* coreSelection = core(selection);
     if (!coreSelection)
         return FALSE;
@@ -159,6 +166,9 @@ static gboolean webkitAccessibleSelectionClearSelection(AtkSelection* selection)
 
 static AtkObject* webkitAccessibleSelectionRefSelection(AtkSelection* selection, gint index)
 {
+    g_return_val_if_fail(ATK_SELECTION(selection), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(selection), 0);
+
     AccessibilityObject* option = optionFromSelection(selection, index);
     if (option) {
         AtkObject* child = option->wrapper();
@@ -171,6 +181,9 @@ static AtkObject* webkitAccessibleSelectionRefSelection(AtkSelection* selection,
 
 static gint webkitAccessibleSelectionGetSelectionCount(AtkSelection* selection)
 {
+    g_return_val_if_fail(ATK_SELECTION(selection), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(selection), 0);
+
     AccessibilityObject* coreSelection = core(selection);
     if (!coreSelection || !coreSelection->isAccessibilityRenderObject())
         return 0;
@@ -195,9 +208,12 @@ static gint webkitAccessibleSelectionGetSelectionCount(AtkSelection* selection)
 
 static gboolean webkitAccessibleSelectionIsChildSelected(AtkSelection* selection, gint index)
 {
+    g_return_val_if_fail(ATK_SELECTION(selection), FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(selection), FALSE);
+
     AccessibilityObject* coreSelection = core(selection);
     if (!coreSelection)
-        return 0;
+        return FALSE;
 
     AccessibilityObject* option = optionFromList(selection, index);
     if (option && (coreSelection->isListBox() || coreSelection->isMenuList()))
@@ -208,9 +224,12 @@ static gboolean webkitAccessibleSelectionIsChildSelected(AtkSelection* selection
 
 static gboolean webkitAccessibleSelectionRemoveSelection(AtkSelection* selection, gint index)
 {
+    g_return_val_if_fail(ATK_SELECTION(selection), FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(selection), FALSE);
+
     AccessibilityObject* coreSelection = core(selection);
     if (!coreSelection)
-        return 0;
+        return FALSE;
 
     // TODO: This is only getting called if i == 0. What is preventing the rest?
     AccessibilityObject* option = optionFromSelection(selection, index);
@@ -224,6 +243,9 @@ static gboolean webkitAccessibleSelectionRemoveSelection(AtkSelection* selection
 
 static gboolean webkitAccessibleSelectionSelectAllSelection(AtkSelection* selection)
 {
+    g_return_val_if_fail(ATK_SELECTION(selection), FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(selection), FALSE);
+
     AccessibilityObject* coreSelection = core(selection);
     if (!coreSelection || !coreSelection->isMultiSelectable())
         return FALSE;
index 275f34b..7dead16 100644 (file)
@@ -42,6 +42,7 @@
 #include "HTMLTableElement.h"
 #include "RenderElement.h"
 #include "WebKitAccessibleInterfaceText.h"
+#include "WebKitAccessibleUtil.h"
 #include "WebKitAccessibleWrapperAtk.h"
 
 using namespace WebCore;
@@ -91,6 +92,9 @@ static AccessibilityTableCell* cellAtIndex(AtkTable* table, gint index)
 
 static AtkObject* webkitAccessibleTableRefAt(AtkTable* table, gint row, gint column)
 {
+    g_return_val_if_fail(ATK_TABLE(table), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), 0);
+
     AccessibilityTableCell* axCell = cell(table, row, column);
     if (!axCell)
         return 0;
@@ -106,6 +110,9 @@ static AtkObject* webkitAccessibleTableRefAt(AtkTable* table, gint row, gint col
 
 static gint webkitAccessibleTableGetIndexAt(AtkTable* table, gint row, gint column)
 {
+    g_return_val_if_fail(ATK_TABLE(table), -1);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), -1);
+
     AccessibilityTableCell* axCell = cell(table, row, column);
     AccessibilityTable* axTable = static_cast<AccessibilityTable*>(core(table));
     return cellIndex(axCell, axTable);
@@ -113,6 +120,9 @@ static gint webkitAccessibleTableGetIndexAt(AtkTable* table, gint row, gint colu
 
 static gint webkitAccessibleTableGetColumnAtIndex(AtkTable* table, gint index)
 {
+    g_return_val_if_fail(ATK_TABLE(table), -1);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), -1);
+
     AccessibilityTableCell* axCell = cellAtIndex(table, index);
     if (axCell) {
         pair<unsigned, unsigned> columnRange;
@@ -124,6 +134,9 @@ static gint webkitAccessibleTableGetColumnAtIndex(AtkTable* table, gint index)
 
 static gint webkitAccessibleTableGetRowAtIndex(AtkTable* table, gint index)
 {
+    g_return_val_if_fail(ATK_TABLE(table), -1);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), -1);
+
     AccessibilityTableCell* axCell = cellAtIndex(table, index);
     if (axCell) {
         pair<unsigned, unsigned> rowRange;
@@ -135,6 +148,9 @@ static gint webkitAccessibleTableGetRowAtIndex(AtkTable* table, gint index)
 
 static gint webkitAccessibleTableGetNColumns(AtkTable* table)
 {
+    g_return_val_if_fail(ATK_TABLE(table), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), 0);
+
     AccessibilityObject* accTable = core(table);
     if (accTable->isAccessibilityRenderObject())
         return static_cast<AccessibilityTable*>(accTable)->columnCount();
@@ -143,6 +159,9 @@ static gint webkitAccessibleTableGetNColumns(AtkTable* table)
 
 static gint webkitAccessibleTableGetNRows(AtkTable* table)
 {
+    g_return_val_if_fail(ATK_TABLE(table), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), 0);
+
     AccessibilityObject* accTable = core(table);
     if (accTable->isAccessibilityRenderObject())
         return static_cast<AccessibilityTable*>(accTable)->rowCount();
@@ -151,6 +170,9 @@ static gint webkitAccessibleTableGetNRows(AtkTable* table)
 
 static gint webkitAccessibleTableGetColumnExtentAt(AtkTable* table, gint row, gint column)
 {
+    g_return_val_if_fail(ATK_TABLE(table), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), 0);
+
     AccessibilityTableCell* axCell = cell(table, row, column);
     if (axCell) {
         pair<unsigned, unsigned> columnRange;
@@ -162,6 +184,9 @@ static gint webkitAccessibleTableGetColumnExtentAt(AtkTable* table, gint row, gi
 
 static gint webkitAccessibleTableGetRowExtentAt(AtkTable* table, gint row, gint column)
 {
+    g_return_val_if_fail(ATK_TABLE(table), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), 0);
+
     AccessibilityTableCell* axCell = cell(table, row, column);
     if (axCell) {
         pair<unsigned, unsigned> rowRange;
@@ -173,6 +198,9 @@ static gint webkitAccessibleTableGetRowExtentAt(AtkTable* table, gint row, gint
 
 static AtkObject* webkitAccessibleTableGetColumnHeader(AtkTable* table, gint column)
 {
+    g_return_val_if_fail(ATK_TABLE(table), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), 0);
+
     AccessibilityObject* accTable = core(table);
     if (accTable->isAccessibilityRenderObject()) {
         AccessibilityObject::AccessibilityChildrenVector allColumnHeaders;
@@ -191,6 +219,9 @@ static AtkObject* webkitAccessibleTableGetColumnHeader(AtkTable* table, gint col
 
 static AtkObject* webkitAccessibleTableGetRowHeader(AtkTable* table, gint row)
 {
+    g_return_val_if_fail(ATK_TABLE(table), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), 0);
+
     AccessibilityObject* accTable = core(table);
     if (accTable->isAccessibilityRenderObject()) {
         AccessibilityObject::AccessibilityChildrenVector allRowHeaders;
@@ -209,6 +240,9 @@ static AtkObject* webkitAccessibleTableGetRowHeader(AtkTable* table, gint row)
 
 static AtkObject* webkitAccessibleTableGetCaption(AtkTable* table)
 {
+    g_return_val_if_fail(ATK_TABLE(table), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), 0);
+
     AccessibilityObject* accTable = core(table);
     if (accTable->isAccessibilityRenderObject()) {
         Node* node = accTable->node();
@@ -223,6 +257,9 @@ static AtkObject* webkitAccessibleTableGetCaption(AtkTable* table)
 
 static const gchar* webkitAccessibleTableGetColumnDescription(AtkTable* table, gint column)
 {
+    g_return_val_if_fail(ATK_TABLE(table), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), 0);
+
     AtkObject* columnHeader = atk_table_get_column_header(table, column);
     if (columnHeader && ATK_IS_TEXT(columnHeader))
         return atk_text_get_text(ATK_TEXT(columnHeader), 0, -1);
@@ -232,6 +269,9 @@ static const gchar* webkitAccessibleTableGetColumnDescription(AtkTable* table, g
 
 static const gchar* webkitAccessibleTableGetRowDescription(AtkTable* table, gint row)
 {
+    g_return_val_if_fail(ATK_TABLE(table), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), 0);
+
     AtkObject* rowHeader = atk_table_get_row_header(table, row);
     if (rowHeader && ATK_IS_TEXT(rowHeader))
         return atk_text_get_text(ATK_TEXT(rowHeader), 0, -1);
index f3e4cce..7f4160b 100644 (file)
@@ -550,6 +550,9 @@ static void getSelectionOffsetsForObject(AccessibilityObject* coreObject, Visibl
 
 static gchar* webkitAccessibleTextGetText(AtkText* text, gint startOffset, gint endOffset)
 {
+    g_return_val_if_fail(ATK_TEXT(text), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), 0);
+
     AccessibilityObject* coreObject = core(text);
 
     int end = endOffset;
@@ -1076,27 +1079,42 @@ static gchar* webkitAccessibleTextGetTextForOffset(AtkText* text, gint offset, A
 
 static gchar* webkitAccessibleTextGetTextAfterOffset(AtkText* text, gint offset, AtkTextBoundary boundaryType, gint* startOffset, gint* endOffset)
 {
+    g_return_val_if_fail(ATK_TEXT(text), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), 0);
+
     return webkitAccessibleTextGetTextForOffset(text, offset, boundaryType, GetTextPositionAfter, startOffset, endOffset);
 }
 
 static gchar* webkitAccessibleTextGetTextAtOffset(AtkText* text, gint offset, AtkTextBoundary boundaryType, gint* startOffset, gint* endOffset)
 {
+    g_return_val_if_fail(ATK_TEXT(text), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), 0);
+
     return webkitAccessibleTextGetTextForOffset(text, offset, boundaryType, GetTextPositionAt, startOffset, endOffset);
 }
 
 static gchar* webkitAccessibleTextGetTextBeforeOffset(AtkText* text, gint offset, AtkTextBoundary boundaryType, gint* startOffset, gint* endOffset)
 {
+    g_return_val_if_fail(ATK_TEXT(text), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), 0);
+
     return webkitAccessibleTextGetTextForOffset(text, offset, boundaryType, GetTextPositionBefore, startOffset, endOffset);
 }
 
-static gunichar webkitAccessibleTextGetCharacterAtOffset(AtkText*, gint)
+static gunichar webkitAccessibleTextGetCharacterAtOffset(AtkText* text, gint)
 {
+    g_return_val_if_fail(ATK_TEXT(text), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), 0);
+
     notImplemented();
     return 0;
 }
 
 static gint webkitAccessibleTextGetCaretOffset(AtkText* text)
 {
+    g_return_val_if_fail(ATK_TEXT(text), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), 0);
+
     // coreObject is the unignored object whose offset the caller is requesting.
     // focusedObject is the object with the caret. It is likely ignored -- unless it's a link.
     AccessibilityObject* coreObject = core(text);
@@ -1118,6 +1136,9 @@ static gint webkitAccessibleTextGetCaretOffset(AtkText* text)
 
 static AtkAttributeSet* webkitAccessibleTextGetRunAttributes(AtkText* text, gint offset, gint* startOffset, gint* endOffset)
 {
+    g_return_val_if_fail(ATK_TEXT(text), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), 0);
+
     AccessibilityObject* coreObject = core(text);
     AtkAttributeSet* result;
 
@@ -1142,6 +1163,9 @@ static AtkAttributeSet* webkitAccessibleTextGetRunAttributes(AtkText* text, gint
 
 static AtkAttributeSet* webkitAccessibleTextGetDefaultAttributes(AtkText* text)
 {
+    g_return_val_if_fail(ATK_TEXT(text), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), 0);
+
     AccessibilityObject* coreObject = core(text);
     if (!coreObject || !coreObject->isAccessibilityRenderObject())
         return 0;
@@ -1151,6 +1175,9 @@ static AtkAttributeSet* webkitAccessibleTextGetDefaultAttributes(AtkText* text)
 
 static void webkitAccessibleTextGetCharacterExtents(AtkText* text, gint offset, gint* x, gint* y, gint* width, gint* height, AtkCoordType coords)
 {
+    g_return_if_fail(ATK_TEXT(text));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text));
+
     IntRect extents = textExtents(text, offset, 1, coords);
     *x = extents.x();
     *y = extents.y();
@@ -1160,6 +1187,9 @@ static void webkitAccessibleTextGetCharacterExtents(AtkText* text, gint offset,
 
 static void webkitAccessibleTextGetRangeExtents(AtkText* text, gint startOffset, gint endOffset, AtkCoordType coords, AtkTextRectangle* rect)
 {
+    g_return_if_fail(ATK_TEXT(text));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text));
+
     IntRect extents = textExtents(text, startOffset, endOffset - startOffset, coords);
     rect->x = extents.x();
     rect->y = extents.y();
@@ -1169,11 +1199,17 @@ static void webkitAccessibleTextGetRangeExtents(AtkText* text, gint startOffset,
 
 static gint webkitAccessibleTextGetCharacterCount(AtkText* text)
 {
+    g_return_val_if_fail(ATK_TEXT(text), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), 0);
+
     return accessibilityObjectLength(core(text));
 }
 
 static gint webkitAccessibleTextGetOffsetAtPoint(AtkText* text, gint x, gint y, AtkCoordType)
 {
+    g_return_val_if_fail(ATK_TEXT(text), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), 0);
+
     // FIXME: Use the AtkCoordType
     // TODO: Is it correct to ignore range.length?
     IntPoint pos(x, y);
@@ -1183,6 +1219,9 @@ static gint webkitAccessibleTextGetOffsetAtPoint(AtkText* text, gint x, gint y,
 
 static gint webkitAccessibleTextGetNSelections(AtkText* text)
 {
+    g_return_val_if_fail(ATK_TEXT(text), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), 0);
+
     AccessibilityObject* coreObject = core(text);
     VisibleSelection selection = coreObject->selection();
 
@@ -1201,6 +1240,9 @@ static gint webkitAccessibleTextGetNSelections(AtkText* text)
 
 static gchar* webkitAccessibleTextGetSelection(AtkText* text, gint selectionNum, gint* startOffset, gint* endOffset)
 {
+    g_return_val_if_fail(ATK_TEXT(text), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), 0);
+
     // WebCore does not support multiple selection, so anything but 0 does not make sense for now.
     if (selectionNum)
         return 0;
@@ -1218,14 +1260,20 @@ static gchar* webkitAccessibleTextGetSelection(AtkText* text, gint selectionNum,
     return webkitAccessibleTextGetText(text, *startOffset, *endOffset);
 }
 
-static gboolean webkitAccessibleTextAddSelection(AtkText*, gint, gint)
+static gboolean webkitAccessibleTextAddSelection(AtkText* text, gint, gint)
 {
+    g_return_val_if_fail(ATK_TEXT(text), FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), FALSE);
+
     notImplemented();
     return FALSE;
 }
 
 static gboolean webkitAccessibleTextSetSelection(AtkText* text, gint selectionNum, gint startOffset, gint endOffset)
 {
+    g_return_val_if_fail(ATK_TEXT(text), FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), FALSE);
+
     // WebCore does not support multiple selection, so anything but 0 does not make sense for now.
     if (selectionNum)
         return FALSE;
@@ -1262,6 +1310,9 @@ static gboolean webkitAccessibleTextSetSelection(AtkText* text, gint selectionNu
 
 static gboolean webkitAccessibleTextRemoveSelection(AtkText* text, gint selectionNum)
 {
+    g_return_val_if_fail(ATK_TEXT(text), FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), FALSE);
+
     // WebCore does not support multiple selection, so anything but 0 does not make sense for now.
     if (selectionNum)
         return FALSE;
@@ -1278,8 +1329,10 @@ static gboolean webkitAccessibleTextRemoveSelection(AtkText* text, gint selectio
 
 static gboolean webkitAccessibleTextSetCaretOffset(AtkText* text, gint offset)
 {
-    AccessibilityObject* coreObject = core(text);
+    g_return_val_if_fail(ATK_TEXT(text), FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(text), FALSE);
 
+    AccessibilityObject* coreObject = core(text);
     if (!coreObject->isAccessibilityRenderObject())
         return FALSE;
 
index 6ba7424..dd64982 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "AccessibilityObject.h"
 #include "HTMLNames.h"
+#include "WebKitAccessibleUtil.h"
 #include "WebKitAccessibleWrapperAtk.h"
 
 using namespace WebCore;
@@ -38,6 +39,9 @@ static AccessibilityObject* core(AtkValue* value)
 
 static void webkitAccessibleValueGetCurrentValue(AtkValue* value, GValue* gValue)
 {
+    g_return_if_fail(ATK_VALUE(value));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(value));
+
     memset(gValue,  0, sizeof(GValue));
     g_value_init(gValue, G_TYPE_FLOAT);
     g_value_set_float(gValue, core(value)->valueForRange());
@@ -45,6 +49,9 @@ static void webkitAccessibleValueGetCurrentValue(AtkValue* value, GValue* gValue
 
 static void webkitAccessibleValueGetMaximumValue(AtkValue* value, GValue* gValue)
 {
+    g_return_if_fail(ATK_VALUE(value));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(value));
+
     memset(gValue,  0, sizeof(GValue));
     g_value_init(gValue, G_TYPE_FLOAT);
     g_value_set_float(gValue, core(value)->maxValueForRange());
@@ -52,6 +59,9 @@ static void webkitAccessibleValueGetMaximumValue(AtkValue* value, GValue* gValue
 
 static void webkitAccessibleValueGetMinimumValue(AtkValue* value, GValue* gValue)
 {
+    g_return_if_fail(ATK_VALUE(value));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(value));
+
     memset(gValue,  0, sizeof(GValue));
     g_value_init(gValue, G_TYPE_FLOAT);
     g_value_set_float(gValue, core(value)->minValueForRange());
@@ -59,6 +69,9 @@ static void webkitAccessibleValueGetMinimumValue(AtkValue* value, GValue* gValue
 
 static gboolean webkitAccessibleValueSetCurrentValue(AtkValue* value, const GValue* gValue)
 {
+    g_return_val_if_fail(ATK_VALUE(value), FALSE);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(value), FALSE);
+
     double newValue;
     if (G_VALUE_HOLDS_DOUBLE(gValue))
         newValue = g_value_get_double(gValue);
@@ -77,7 +90,7 @@ static gboolean webkitAccessibleValueSetCurrentValue(AtkValue* value, const GVal
     else if (G_VALUE_HOLDS_UINT(gValue))
         newValue = g_value_get_uint(gValue);
     else
-        return false;
+        return FALSE;
 
     AccessibilityObject* coreObject = core(value);
     if (!coreObject->canSetValueAttribute())
@@ -93,6 +106,9 @@ static gboolean webkitAccessibleValueSetCurrentValue(AtkValue* value, const GVal
 
 static void webkitAccessibleValueGetMinimumIncrement(AtkValue* value, GValue* gValue)
 {
+    g_return_if_fail(ATK_VALUE(value));
+    returnIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(value));
+
     memset(gValue,  0, sizeof(GValue));
     g_value_init(gValue, G_TYPE_FLOAT);
 
index 35c78f3..bc7065f 100644 (file)
@@ -33,6 +33,26 @@ class IntRect;
 class VisibleSelection;
 }
 
+// An existing accessibility object is considered to be invalid whether it's already
+// detached or if it's not but just updating the layout will detach it anyway.
+#define returnIfWebKitAccessibleIsInvalid(webkitAccessible) G_STMT_START { \
+    if (!webkitAccessible || webkitAccessibleIsDetached(webkitAccessible)) { \
+        return; \
+    } else { \
+        webkitAccessibleGetAccessibilityObject(webkitAccessible)->updateBackingStore(); \
+        if (webkitAccessibleIsDetached(webkitAccessible)) \
+            return; \
+    }; } G_STMT_END
+
+#define returnValIfWebKitAccessibleIsInvalid(webkitAccessible, val) G_STMT_START { \
+    if (!webkitAccessible || webkitAccessibleIsDetached(webkitAccessible)) { \
+        return (val); \
+    } else { \
+        webkitAccessibleGetAccessibilityObject(webkitAccessible)->updateBackingStore(); \
+        if (webkitAccessibleIsDetached(webkitAccessible)) \
+            return (val); \
+    }; } G_STMT_END
+
 AtkAttributeSet* addToAtkAttributeSet(AtkAttributeSet*, const char* name, const char* value);
 
 void contentsRelativeToAtkCoordinateType(WebCore::AccessibilityObject*, AtkCoordType, WebCore::IntRect, gint* x, gint* y, gint* width = 0, gint* height = 0);
index 2c61fcf..ad88bda 100644 (file)
@@ -96,25 +96,21 @@ static AccessibilityObject* fallbackObject()
     return object;
 }
 
-static AccessibilityObject* core(WebKitAccessible* accessible)
-{
-    if (!accessible)
-        return 0;
-
-    return accessible->m_object;
-}
-
 static AccessibilityObject* core(AtkObject* object)
 {
     if (!WEBKIT_IS_ACCESSIBLE(object))
         return 0;
 
-    return core(WEBKIT_ACCESSIBLE(object));
+    return webkitAccessibleGetAccessibilityObject(WEBKIT_ACCESSIBLE(object));
 }
 
 static const gchar* webkitAccessibleGetName(AtkObject* object)
 {
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE(object), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(object), 0);
+
     AccessibilityObject* coreObject = core(object);
+
     if (!coreObject->isAccessibilityRenderObject())
         return cacheAndReturnAtkProperty(object, AtkCachedAccessibleName, coreObject->stringValue());
 
@@ -169,6 +165,9 @@ static const gchar* webkitAccessibleGetName(AtkObject* object)
 
 static const gchar* webkitAccessibleGetDescription(AtkObject* object)
 {
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE(object), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(object), 0);
+
     AccessibilityObject* coreObject = core(object);
     Node* node = 0;
     if (coreObject->isAccessibilityRenderObject())
@@ -272,6 +271,9 @@ static AtkObject* atkParentOfRootObject(AtkObject* object)
 
 static AtkObject* webkitAccessibleGetParent(AtkObject* object)
 {
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE(object), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(object), 0);
+
     // Check first if the parent has been already set.
     AtkObject* accessibleParent = ATK_OBJECT_CLASS(webkitAccessibleParentClass)->get_parent(object);
     if (accessibleParent)
@@ -319,6 +321,9 @@ static gint getNChildrenForTable(AccessibilityObject* coreObject)
 
 static gint webkitAccessibleGetNChildren(AtkObject* object)
 {
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE(object), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(object), 0);
+
     AccessibilityObject* coreObject = core(object);
 
     // Tables should be treated in a different way because rows should
@@ -356,6 +361,9 @@ static AccessibilityObject* getChildForTable(AccessibilityObject* coreObject, gi
 
 static AtkObject* webkitAccessibleRefChild(AtkObject* object, gint index)
 {
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE(object), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(object), 0);
+
     if (index < 0)
         return 0;
 
@@ -420,6 +428,9 @@ static gint getIndexInParentForCellInRow(AccessibilityObject* coreObject)
 
 static gint webkitAccessibleGetIndexInParent(AtkObject* object)
 {
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE(object), -1);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(object), -1);
+
     AccessibilityObject* coreObject = core(object);
     AccessibilityObject* parent = coreObject->parentObjectUnignored();
 
@@ -452,6 +463,9 @@ static gint webkitAccessibleGetIndexInParent(AtkObject* object)
 
 static AtkAttributeSet* webkitAccessibleGetAttributes(AtkObject* object)
 {
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE(object), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(object), 0);
+
     AtkAttributeSet* attributeSet = 0;
 #if PLATFORM(GTK)
     attributeSet = addToAtkAttributeSet(attributeSet, "toolkit", "WebKitGtk");
@@ -626,6 +640,9 @@ static AtkRole atkRole(AccessibilityRole role)
 
 static AtkRole webkitAccessibleGetRole(AtkObject* object)
 {
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE(object), ATK_ROLE_UNKNOWN);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(object), ATK_ROLE_UNKNOWN);
+
     AccessibilityObject* coreObject = core(object);
 
     if (!coreObject)
@@ -766,9 +783,15 @@ static void setAtkStateSetFromCoreObject(AccessibilityObject* coreObject, AtkSta
 
 static AtkStateSet* webkitAccessibleRefStateSet(AtkObject* object)
 {
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE(object), 0);
+
     AtkStateSet* stateSet = ATK_OBJECT_CLASS(webkitAccessibleParentClass)->ref_state_set(object);
     AccessibilityObject* coreObject = core(object);
 
+    // Make sure the layout is updated to really know whether the object
+    // is defunct or not, so we can return the proper state.
+    coreObject->updateBackingStore();
+
     if (coreObject == fallbackObject()) {
         atk_state_set_add_state(stateSet, ATK_STATE_DEFUNCT);
         return stateSet;
@@ -785,6 +808,9 @@ static AtkStateSet* webkitAccessibleRefStateSet(AtkObject* object)
 
 static AtkRelationSet* webkitAccessibleRefRelationSet(AtkObject* object)
 {
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE(object), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(object), 0);
+
     AtkRelationSet* relationSet = ATK_OBJECT_CLASS(webkitAccessibleParentClass)->ref_relation_set(object);
     AccessibilityObject* coreObject = core(object);
 
@@ -805,11 +831,14 @@ static void webkitAccessibleInit(AtkObject* object, gpointer data)
 
 static const gchar* webkitAccessibleGetObjectLocale(AtkObject* object)
 {
-    if (ATK_IS_DOCUMENT(object)) {
-        AccessibilityObject* coreObject = core(object);
-        if (!coreObject)
-            return 0;
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE(object), 0);
+    returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(object), 0);
+
+    AccessibilityObject* coreObject = core(object);
+    if (!coreObject)
+        return 0;
 
+    if (ATK_IS_DOCUMENT(object)) {
         // TODO: Should we fall back on lang xml:lang when the following comes up empty?
         String language = coreObject->language();
         if (!language.isEmpty())
@@ -1096,7 +1125,7 @@ void webkitAccessibleDetach(WebKitAccessible* accessible)
 {
     ASSERT(accessible->m_object);
 
-    if (core(accessible)->roleValue() == WebAreaRole)
+    if (accessible->m_object->roleValue() == WebAreaRole)
         g_signal_emit_by_name(accessible, "state-change", "defunct", true);
 
     // We replace the WebCore AccessibilityObject with a fallback object that
@@ -1105,6 +1134,12 @@ void webkitAccessibleDetach(WebKitAccessible* accessible)
     accessible->m_object = fallbackObject();
 }
 
+bool webkitAccessibleIsDetached(WebKitAccessible* accessible)
+{
+    ASSERT(accessible->m_object);
+    return accessible->m_object == fallbackObject();
+}
+
 AtkObject* webkitAccessibleGetFocusedElement(WebKitAccessible* accessible)
 {
     if (!accessible->m_object)
index 3080aeb..0d47301 100644 (file)
@@ -77,6 +77,8 @@ WebCore::AccessibilityObject* webkitAccessibleGetAccessibilityObject(WebKitAcces
 
 void webkitAccessibleDetach(WebKitAccessible*);
 
+bool webkitAccessibleIsDetached(WebKitAccessible*);
+
 AtkObject* webkitAccessibleGetFocusedElement(WebKitAccessible*);
 
 WebCore::AccessibilityObject* objectFocusedAndCaretOffsetUnignored(WebCore::AccessibilityObject*, int& offset);