[GTK] WebCore::returnString is unsafe and should be removed!
authormario@webkit.org <mario@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Mar 2013 17:06:15 +0000 (17:06 +0000)
committermario@webkit.org <mario@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Mar 2013 17:06:15 +0000 (17:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=110423

Reviewed by Martin Robinson.

Remove returnString() and replace it in callers with a new
function that will cache and return the values of string
properties for ATK interfaces in the private section of the
wrapper AtkObject WebKitAccessible.

* accessibility/atk/WebKitAccessibleUtil.cpp: Remove returnString().
* accessibility/atk/WebKitAccessibleUtil.h: Ditto.

* accessibility/atk/WebKitAccessibleWrapperAtk.cpp:
(_WebKitAccessiblePrivate): New private structure to store cached
values of string property for the different ATK interfaces.
(cacheAndReturnAtkProperty): New helper function to make sure the
returned const gchar* value is previously cached in the private
section of the wrapper AtkObject.
(webkitAccessibleGetName): Use the new helper function.
(webkitAccessibleGetDescription): Ditto.
(webkitAccessibleInit): Initialize pointer to private structure.
(webkitAccessibleFinalize): Remove unneeded code.
(webkitAccessibleClassInit): Add private struct to class type/
* accessibility/atk/WebKitAccessibleWrapperAtk.h:
(_WebKitAccessible): New member pointing to the private structure,
made the new helper function cacheAndReturnAtkProperty() available
to external callers (implementation files for ATK interfaces).
(AtkCachedProperty): New enum to allow reusing code when calling
cacheAndReturnAtkProperty() to cache and return different properties.

* accessibility/atk/WebKitAccessibleInterfaceAction.cpp:
(webkitAccessibleActionGetKeybinding): Replace calls to returnString()
with calls to the new helper function cacheAndReturnAtkProperty().
(webkitAccessibleActionGetName): Ditto.
* accessibility/atk/WebKitAccessibleInterfaceDocument.cpp:
(documentAttributeValue): Ditto.
(webkitAccessibleDocumentGetLocale): Ditto.
* accessibility/atk/WebKitAccessibleInterfaceImage.cpp:
(webkitAccessibleImageGetImageDescription): Ditto.

Remove returnString() from WebKitAccessibleHyperlink (which is not
an AtkObject, but a GObject) as well, replacing it in callers with
simple code that will cache and return the required values in the
private section of these kind of objects.

* accessibility/atk/WebKitAccessibleHyperlink.cpp:
(_WebKitAccessibleHyperlinkPrivate): Added two new fields to cache
string values for the key binding and name properties from the
AtkAction interface, which is implemented by AtkHyperlink.
(webkitAccessibleHyperlinkActionGetKeybinding): Cache the string
value for the key binding before returning a const gchar* pointer.
(webkitAccessibleHyperlinkActionGetName): Ditto.
(webkitAccessibleHyperlinkGetURI): Do not cache the URI here, as
this function returns a gchar* that will be owned by the caller.

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

Source/WebCore/ChangeLog
Source/WebCore/accessibility/atk/WebKitAccessibleHyperlink.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceAction.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceDocument.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceImage.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleUtil.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleUtil.h
Source/WebCore/accessibility/atk/WebKitAccessibleWrapperAtk.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleWrapperAtk.h

index 0de5dd77f7b5197a8999a8a73ff71acceb6023b9..959b67390fa74bd2d469bb321bdb1781afb3c3d0 100644 (file)
@@ -1,3 +1,61 @@
+2013-03-04  Mario Sanchez Prada  <mario.prada@samsung.com>
+
+        [GTK] WebCore::returnString is unsafe and should be removed!
+        https://bugs.webkit.org/show_bug.cgi?id=110423
+
+        Reviewed by Martin Robinson.
+
+        Remove returnString() and replace it in callers with a new
+        function that will cache and return the values of string
+        properties for ATK interfaces in the private section of the
+        wrapper AtkObject WebKitAccessible.
+
+        * accessibility/atk/WebKitAccessibleUtil.cpp: Remove returnString().
+        * accessibility/atk/WebKitAccessibleUtil.h: Ditto.
+
+        * accessibility/atk/WebKitAccessibleWrapperAtk.cpp:
+        (_WebKitAccessiblePrivate): New private structure to store cached
+        values of string property for the different ATK interfaces.
+        (cacheAndReturnAtkProperty): New helper function to make sure the
+        returned const gchar* value is previously cached in the private
+        section of the wrapper AtkObject.
+        (webkitAccessibleGetName): Use the new helper function.
+        (webkitAccessibleGetDescription): Ditto.
+        (webkitAccessibleInit): Initialize pointer to private structure.
+        (webkitAccessibleFinalize): Remove unneeded code.
+        (webkitAccessibleClassInit): Add private struct to class type/
+        * accessibility/atk/WebKitAccessibleWrapperAtk.h:
+        (_WebKitAccessible): New member pointing to the private structure,
+        made the new helper function cacheAndReturnAtkProperty() available
+        to external callers (implementation files for ATK interfaces).
+        (AtkCachedProperty): New enum to allow reusing code when calling
+        cacheAndReturnAtkProperty() to cache and return different properties.
+
+        * accessibility/atk/WebKitAccessibleInterfaceAction.cpp:
+        (webkitAccessibleActionGetKeybinding): Replace calls to returnString()
+        with calls to the new helper function cacheAndReturnAtkProperty().
+        (webkitAccessibleActionGetName): Ditto.
+        * accessibility/atk/WebKitAccessibleInterfaceDocument.cpp:
+        (documentAttributeValue): Ditto.
+        (webkitAccessibleDocumentGetLocale): Ditto.
+        * accessibility/atk/WebKitAccessibleInterfaceImage.cpp:
+        (webkitAccessibleImageGetImageDescription): Ditto.
+
+        Remove returnString() from WebKitAccessibleHyperlink (which is not
+        an AtkObject, but a GObject) as well, replacing it in callers with
+        simple code that will cache and return the required values in the
+        private section of these kind of objects.
+
+        * accessibility/atk/WebKitAccessibleHyperlink.cpp:
+        (_WebKitAccessibleHyperlinkPrivate): Added two new fields to cache
+        string values for the key binding and name properties from the
+        AtkAction interface, which is implemented by AtkHyperlink.
+        (webkitAccessibleHyperlinkActionGetKeybinding): Cache the string
+        value for the key binding before returning a const gchar* pointer.
+        (webkitAccessibleHyperlinkActionGetName): Ditto.
+        (webkitAccessibleHyperlinkGetURI): Do not cache the URI here, as
+        this function returns a gchar* that will be owned by the caller.
+
 2013-03-04  peavo@outlook.com  <peavo@outlook.com>
 
         [Curl] Compile fix after r144216
index af1e4295ecbe7eb3d2079e84dda4da5484a48078..66012486d8f3bd7e1e898af87967d504798ae8e3 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010, 2011, 2012 Igalia S.L.
+ * Copyright (C) 2013 Samsung Electronics
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -41,6 +42,10 @@ using namespace WebCore;
 
 struct _WebKitAccessibleHyperlinkPrivate {
     WebKitAccessible* hyperlinkImpl;
+
+    // We cache these values so we can return them as const values.
+    CString actionName;
+    CString actionKeyBinding;
 };
 
 #define WEBKIT_ACCESSIBLE_HYPERLINK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_ACCESSIBLE_HYPERLINK, WebKitAccessibleHyperlinkPrivate))
@@ -124,33 +129,39 @@ 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);
 
-    if (!ATK_IS_ACTION(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl))
+    WebKitAccessibleHyperlinkPrivate* priv = WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv;
+    g_return_val_if_fail(priv->hyperlinkImpl, 0);
+
+    if (!ATK_IS_ACTION(priv->hyperlinkImpl))
         return 0;
 
     AccessibilityObject* coreObject = core(action);
     if (!coreObject)
         return 0;
 
-    return returnString(coreObject->accessKey().string());
+    priv->actionKeyBinding = coreObject->accessKey().string().utf8();
+    return priv->actionKeyBinding.data();
 }
 
 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);
 
-    if (!ATK_IS_ACTION(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl))
+    WebKitAccessibleHyperlinkPrivate* priv = WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv;
+    g_return_val_if_fail(priv->hyperlinkImpl, 0);
+
+    if (!ATK_IS_ACTION(priv->hyperlinkImpl))
         return 0;
 
     AccessibilityObject* coreObject = core(action);
     if (!coreObject)
         return 0;
 
-    return returnString(coreObject->actionVerb());
+    priv->actionName = coreObject->actionVerb().utf8();
+    return priv->actionName.data();
 }
 
 static void atkActionInterfaceInit(AtkActionIface* iface)
@@ -173,7 +184,7 @@ static gchar* webkitAccessibleHyperlinkGetURI(AtkHyperlink* link, gint index)
     if (!coreObject || coreObject->url().isNull())
         return 0;
 
-    return g_strdup(returnString(coreObject->url().string()));
+    return g_strdup(coreObject->url().string().utf8().data());
 }
 
 static AtkObject* webkitAccessibleHyperlinkGetObject(AtkHyperlink* link, gint index)
index 3b679b91a2e2d08e90462dacf2b51a43815d439c..eb18beb6de7a97c144ed35b59ed19bbad1192cf6 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) 2008 Nuanti Ltd.
  * Copyright (C) 2009 Jan Alonzo
  * Copyright (C) 2012 Igalia S.L.
+ * Copyright (C) 2013 Samsung Electronics
  *
  * Portions from Mozilla a11y, copyright as follows:
  *
@@ -70,13 +71,13 @@ static const gchar* webkitAccessibleActionGetKeybinding(AtkAction* action, gint
 {
     g_return_val_if_fail(!index, 0);
     // FIXME: Construct a proper keybinding string.
-    return returnString(core(action)->accessKey().string());
+    return cacheAndReturnAtkProperty(ATK_OBJECT(action), AtkCachedActionKeyBinding, core(action)->accessKey().string());
 }
 
 static const gchar* webkitAccessibleActionGetName(AtkAction* action, gint index)
 {
     g_return_val_if_fail(!index, 0);
-    return returnString(core(action)->actionVerb());
+    return cacheAndReturnAtkProperty(ATK_OBJECT(action), AtkCachedActionName, core(action)->actionVerb());
 }
 
 void webkitAccessibleActionInterfaceInit(AtkActionIface* iface)
index 8858f37211eb10d543905b8b28070453f09522dd..dac1bbbaa11aee5363529fa54d65b1499d28e3cb 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) 2008 Nuanti Ltd.
  * Copyright (C) 2009 Jan Alonzo
  * Copyright (C) 2012 Igalia S.L.
+ * Copyright (C) 2013 Samsung Electronics
  *
  * Portions from Mozilla a11y, copyright as follows:
  *
@@ -56,15 +57,21 @@ static const gchar* documentAttributeValue(AtkDocument* document, const gchar* a
         return 0;
 
     String value = String();
-    if (!g_ascii_strcasecmp(attribute, "DocType") && coreDocument->doctype())
+    AtkCachedProperty atkCachedProperty;
+
+    if (!g_ascii_strcasecmp(attribute, "DocType") && coreDocument->doctype()) {
         value = coreDocument->doctype()->name();
-    else if (!g_ascii_strcasecmp(attribute, "Encoding"))
+        atkCachedProperty = AtkCachedDocumentType;
+    } else if (!g_ascii_strcasecmp(attribute, "Encoding")) {
         value = coreDocument->charset();
-    else if (!g_ascii_strcasecmp(attribute, "URI"))
+        atkCachedProperty = AtkCachedDocumentEncoding;
+    } else if (!g_ascii_strcasecmp(attribute, "URI")) {
         value = coreDocument->documentURI();
+        atkCachedProperty = AtkCachedDocumentURI;
+    }
 
     if (!value.isEmpty())
-        return returnString(value);
+        return cacheAndReturnAtkProperty(ATK_OBJECT(document), atkCachedProperty, value);
 
     return 0;
 }
@@ -93,7 +100,7 @@ static const gchar* webkitAccessibleDocumentGetLocale(AtkDocument* document)
     // TODO: Should we fall back on lang xml:lang when the following comes up empty?
     String language = core(document)->language();
     if (!language.isEmpty())
-        return returnString(language);
+        return cacheAndReturnAtkProperty(ATK_OBJECT(document), AtkCachedDocumentLocale, language);
 
     return 0;
 }
index 679d7e721bede5f5debfa40a181682e644d84b1c..6d7df1279914f17e22aab6ec0797c46a952fa29e 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) 2008 Nuanti Ltd.
  * Copyright (C) 2009 Jan Alonzo
  * Copyright (C) 2009, 2012 Igalia S.L.
+ * Copyright (C) 2013 Samsung Electronics
  *
  * Portions from Mozilla a11y, copyright as follows:
  *
@@ -56,7 +57,7 @@ static void webkitAccessibleImageGetImagePosition(AtkImage* image, gint* x, gint
 
 static const gchar* webkitAccessibleImageGetImageDescription(AtkImage* image)
 {
-    return returnString(accessibilityDescription(core(image)));
+    return cacheAndReturnAtkProperty(ATK_OBJECT(image), AtkCachedImageDescription, accessibilityDescription(core(image)));
 }
 
 static void webkitAccessibleImageGetImageSize(AtkImage* image, gint* width, gint* height)
index 8116777cca56c109eba751cd4405e4bd74e45fd7..34a71f17855d75288aa38cb1a94bb4a97a7b9686 100644 (file)
@@ -79,14 +79,6 @@ void contentsRelativeToAtkCoordinateType(AccessibilityObject* coreObject, AtkCoo
         *height = rect.height();
 }
 
-// Used to provide const char* returns.
-const char* returnString(const String& str)
-{
-    static CString returnedString;
-    returnedString = str.utf8();
-    return returnedString.data();
-}
-
 // FIXME: Different kinds of elements are putting the title tag to use
 // in different AX fields. This might not be 100% correct but we will
 // keep it now in order to achieve consistency with previous behavior.
index b54e8fd6db5ba3682fcb8d754869156884c30e91..35c78f379fef781ceab9df5f3a35edbd99c69c36 100644 (file)
@@ -37,8 +37,6 @@ AtkAttributeSet* addToAtkAttributeSet(AtkAttributeSet*, const char* name, const
 
 void contentsRelativeToAtkCoordinateType(WebCore::AccessibilityObject*, AtkCoordType, WebCore::IntRect, gint* x, gint* y, gint* width = 0, gint* height = 0);
 
-const char* returnString(const String&);
-
 String accessibilityTitle(WebCore::AccessibilityObject*);
 
 String accessibilityDescription(WebCore::AccessibilityObject*);
index 92e1f679ae0216bca5c2454dbb5ab0cd2d80dc73..dd4702ad1fded312c7e8f37a0d12411099525983 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) 2008 Nuanti Ltd.
  * Copyright (C) 2009 Jan Alonzo
  * Copyright (C) 2009, 2010, 2011, 2012 Igalia S.L.
+ * Copyright (C) 2013 Samsung Electronics
  *
  * Portions from Mozilla a11y, copyright as follows:
  *
 
 using namespace WebCore;
 
+struct _WebKitAccessiblePrivate {
+    // Cached data for AtkObject.
+    CString accessibleName;
+    CString accessibleDescription;
+
+    // Cached data for AtkAction.
+    CString actionName;
+    CString actionKeyBinding;
+
+    // Cached data for AtkDocument.
+    CString documentLocale;
+    CString documentType;
+    CString documentEncoding;
+    CString documentURI;
+
+    // Cached data for AtkImage.
+    CString imageDescription;
+};
+
+#define WEBKIT_ACCESSIBLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_ACCESSIBLE, WebKitAccessiblePrivate))
+
 static AccessibilityObject* fallbackObject()
 {
     // FIXME: An AXObjectCache with a Document is meaningless.
@@ -100,7 +122,7 @@ static const gchar* webkitAccessibleGetName(AtkObject* object)
 {
     AccessibilityObject* coreObject = core(object);
     if (!coreObject->isAccessibilityRenderObject())
-        return returnString(coreObject->stringValue());
+        return cacheAndReturnAtkProperty(object, AtkCachedAccessibleName, coreObject->stringValue());
 
     if (coreObject->isFieldset()) {
         AccessibilityObject* label = coreObject->titleUIElement();
@@ -122,7 +144,7 @@ static const gchar* webkitAccessibleGetName(AtkObject* object)
         // Try text under the node.
         String textUnder = coreObject->textUnderElement();
         if (textUnder.length())
-            return returnString(textUnder);
+            return cacheAndReturnAtkProperty(object, AtkCachedAccessibleName, textUnder);
     }
 
     if (coreObject->isImage() || coreObject->isInputImage()) {
@@ -131,7 +153,7 @@ static const gchar* webkitAccessibleGetName(AtkObject* object)
             // Get the attribute rather than altText String so as not to fall back on title.
             String alt = toHTMLElement(node)->getAttribute(HTMLNames::altAttr);
             if (!alt.isEmpty())
-                return returnString(alt);
+                return cacheAndReturnAtkProperty(object, AtkCachedAccessibleName, alt);
         }
     }
 
@@ -139,16 +161,16 @@ static const gchar* webkitAccessibleGetName(AtkObject* object)
     if (coreObject->isWebArea()) {
         Document* document = coreObject->document();
         if (document)
-            return returnString(document->title());
+            return cacheAndReturnAtkProperty(object, AtkCachedAccessibleName, document->title());
     }
 
     // Nothing worked so far, try with the AccessibilityObject's
     // title() before going ahead with stringValue().
     String axTitle = accessibilityTitle(coreObject);
     if (!axTitle.isEmpty())
-        return returnString(axTitle);
+        return cacheAndReturnAtkProperty(object, AtkCachedAccessibleName, axTitle);
 
-    return returnString(coreObject->stringValue());
+    return cacheAndReturnAtkProperty(object, AtkCachedAccessibleName, coreObject->stringValue());
 }
 
 static const gchar* webkitAccessibleGetDescription(AtkObject* object)
@@ -158,22 +180,22 @@ static const gchar* webkitAccessibleGetDescription(AtkObject* object)
     if (coreObject->isAccessibilityRenderObject())
         node = coreObject->node();
     if (!node || !node->isHTMLElement() || coreObject->ariaRoleAttribute() != UnknownRole)
-        return returnString(accessibilityDescription(coreObject));
+        return cacheAndReturnAtkProperty(object, AtkCachedAccessibleDescription, accessibilityDescription(coreObject));
 
     // atk_table_get_summary returns an AtkObject. We have no summary object, so expose summary here.
     if (coreObject->roleValue() == TableRole) {
         String summary = static_cast<HTMLTableElement*>(node)->summary();
         if (!summary.isEmpty())
-            return returnString(summary);
+            return cacheAndReturnAtkProperty(object, AtkCachedAccessibleDescription, summary);
     }
 
     // The title attribute should be reliably available as the object's descripton.
     // We do not want to fall back on other attributes in its absence. See bug 25524.
     String title = toHTMLElement(node)->title();
     if (!title.isEmpty())
-        return returnString(title);
+        return cacheAndReturnAtkProperty(object, AtkCachedAccessibleDescription, title);
 
-    return returnString(accessibilityDescription(coreObject));
+    return cacheAndReturnAtkProperty(object, AtkCachedAccessibleDescription, accessibilityDescription(coreObject));
 }
 
 static void setAtkRelationSetFromCoreObject(AccessibilityObject* coreObject, AtkRelationSet* relationSet)
@@ -763,14 +785,13 @@ static void webkitAccessibleInit(AtkObject* object, gpointer data)
     if (ATK_OBJECT_CLASS(webkitAccessibleParentClass)->initialize)
         ATK_OBJECT_CLASS(webkitAccessibleParentClass)->initialize(object, data);
 
-    WEBKIT_ACCESSIBLE(object)->m_object = reinterpret_cast<AccessibilityObject*>(data);
+    WebKitAccessible* accessible = WEBKIT_ACCESSIBLE(object);
+    accessible->m_object = reinterpret_cast<AccessibilityObject*>(data);
+    accessible->priv = WEBKIT_ACCESSIBLE_GET_PRIVATE(accessible);
 }
 
 static void webkitAccessibleFinalize(GObject* object)
 {
-    // This is a good time to clear the return buffer.
-    returnString(String());
-
     G_OBJECT_CLASS(webkitAccessibleParentClass)->finalize(object);
 }
 
@@ -793,6 +814,8 @@ static void webkitAccessibleClassInit(AtkObjectClass* klass)
     klass->get_index_in_parent = webkitAccessibleGetIndexInParent;
     klass->get_attributes = webkitAccessibleGetAttributes;
     klass->ref_relation_set = webkitAccessibleRefRelationSet;
+
+    g_type_class_add_private(klass, sizeof(WebKitAccessiblePrivate));
 }
 
 GType
@@ -1121,4 +1144,58 @@ AccessibilityObject* objectFocusedAndCaretOffsetUnignored(AccessibilityObject* r
     return firstUnignoredParent;
 }
 
+const char* cacheAndReturnAtkProperty(AtkObject* object, AtkCachedProperty property, String value)
+{
+    WebKitAccessiblePrivate* priv = WEBKIT_ACCESSIBLE(object)->priv;
+    CString* propertyPtr = 0;
+
+    switch (property) {
+    case AtkCachedAccessibleName:
+        propertyPtr = &priv->accessibleName;
+        break;
+
+    case AtkCachedAccessibleDescription:
+        propertyPtr = &priv->accessibleDescription;
+        break;
+
+    case AtkCachedActionName:
+        propertyPtr = &priv->actionName;
+        break;
+
+    case AtkCachedActionKeyBinding:
+        propertyPtr = &priv->actionKeyBinding;
+        break;
+
+    case AtkCachedDocumentLocale:
+        propertyPtr = &priv->documentLocale;
+        break;
+
+    case AtkCachedDocumentType:
+        propertyPtr = &priv->documentType;
+        break;
+
+    case AtkCachedDocumentEncoding:
+        propertyPtr = &priv->documentEncoding;
+        break;
+
+    case AtkCachedDocumentURI:
+        propertyPtr = &priv->documentURI;
+        break;
+
+    case AtkCachedImageDescription:
+        propertyPtr = &priv->imageDescription;
+        break;
+
+    default:
+        ASSERT_NOT_REACHED();
+    }
+
+    // Don't invalidate old memory if not stricly needed, since other
+    // callers might be still holding on to it.
+    if (*propertyPtr != value.utf8())
+        *propertyPtr = value.utf8();
+
+    return (*propertyPtr).data();
+}
+
 #endif // HAVE(ACCESSIBILITY)
index ce6e7b950bb0bd3ab8ead01d75338ec01aa247c1..3080aeb93ead0d683e658a0e0304a5ec531627e9 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) 2008 Nuanti Ltd.
  * Copyright (C) 2009 Jan Alonzo
  * Copyright (C) 2009, 2010, 2011, 2012 Igalia S.L.
+ * Copyright (C) 2013 Samsung Electronics
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -25,6 +26,7 @@
 #if HAVE(ACCESSIBILITY)
 
 #include <atk/atk.h>
+#include <wtf/text/WTFString.h>
 
 namespace WebCore {
 class AccessibilityObject;
@@ -41,16 +43,32 @@ G_BEGIN_DECLS
 
 typedef struct _WebKitAccessible                WebKitAccessible;
 typedef struct _WebKitAccessibleClass           WebKitAccessibleClass;
+typedef struct _WebKitAccessiblePrivate         WebKitAccessiblePrivate;
+
 
 struct _WebKitAccessible {
     AtkObject parent;
     WebCore::AccessibilityObject* m_object;
+
+    WebKitAccessiblePrivate *priv;
 };
 
 struct _WebKitAccessibleClass {
     AtkObjectClass parentClass;
 };
 
+enum AtkCachedProperty {
+    AtkCachedAccessibleName,
+    AtkCachedAccessibleDescription,
+    AtkCachedActionName,
+    AtkCachedActionKeyBinding,
+    AtkCachedDocumentLocale,
+    AtkCachedDocumentType,
+    AtkCachedDocumentEncoding,
+    AtkCachedDocumentURI,
+    AtkCachedImageDescription
+};
+
 GType webkitAccessibleGetType(void) G_GNUC_CONST;
 
 WebKitAccessible* webkitAccessibleNew(WebCore::AccessibilityObject*);
@@ -63,6 +81,8 @@ AtkObject* webkitAccessibleGetFocusedElement(WebKitAccessible*);
 
 WebCore::AccessibilityObject* objectFocusedAndCaretOffsetUnignored(WebCore::AccessibilityObject*, int& offset);
 
+const char* cacheAndReturnAtkProperty(AtkObject*, AtkCachedProperty, String value);
+
 G_END_DECLS
 
 #endif