From: Wonki Kim Date: Tue, 15 Sep 2020 08:21:06 +0000 (+0900) Subject: fix unexpected crashing caused by nullptr mNode X-Git-Tag: submit/tizen/20200915.093548~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9d7e18a9110bad4102d1c2a2505c2f7540b7ea91;p=platform%2Fcore%2Fuifw%2Faurum.git fix unexpected crashing caused by nullptr mNode atspi api return nullptr sometime. this patch handles the case to avoid crashing. Change-Id: I3199e62bd79a27a5cca87f42d0b83ff32dabee98 --- diff --git a/libaurum/inc/Impl/Accessibility/AtspiAccessibleNode.h b/libaurum/inc/Impl/Accessibility/AtspiAccessibleNode.h index 85fe9be..eec9007 100644 --- a/libaurum/inc/Impl/Accessibility/AtspiAccessibleNode.h +++ b/libaurum/inc/Impl/Accessibility/AtspiAccessibleNode.h @@ -41,6 +41,12 @@ public: */ std::shared_ptr getParent() const override; + /** + * @brief TBD + * @since_tizen 5.5 + */ + bool isValid() const; + public: /** * @brief TBD diff --git a/libaurum/src/Impl/Accessibility/AtspiAccessibleNode.cc b/libaurum/src/Impl/Accessibility/AtspiAccessibleNode.cc index 00e530a..2e5e543 100644 --- a/libaurum/src/Impl/Accessibility/AtspiAccessibleNode.cc +++ b/libaurum/src/Impl/Accessibility/AtspiAccessibleNode.cc @@ -9,57 +9,61 @@ AtspiAccessibleNode::AtspiAccessibleNode(AtspiAccessible *node) : mNode{node} { - GArray *ifaces = atspi_accessible_get_interfaces(mNode); - if (ifaces) { - for (unsigned int i = 0; i < ifaces->len; i++) { - char *iface = g_array_index(ifaces, char *, i); - if (!strcmp(iface, "Action")) - mSupportingIfaces |= - static_cast(AccessibleNodeInterface::ACTION); - else if (!strcmp(iface, "Collection")) - mSupportingIfaces |= - static_cast(AccessibleNodeInterface::COLLECTION); - else if (!strcmp(iface, "Component")) - mSupportingIfaces |= - static_cast(AccessibleNodeInterface::COMPONENT); - else if (!strcmp(iface, "Document")) - mSupportingIfaces |= - static_cast(AccessibleNodeInterface::DOCUMENT); - else if (!strcmp(iface, "EditableText")) - mSupportingIfaces |= - static_cast(AccessibleNodeInterface::EDITABLETEXT); - else if (!strcmp(iface, "Hypertext")) - mSupportingIfaces |= - static_cast(AccessibleNodeInterface::HYPERTEXT); - else if (!strcmp(iface, "Image")) - mSupportingIfaces |= - static_cast(AccessibleNodeInterface::IMAGE); - else if (!strcmp(iface, "Selection")) - mSupportingIfaces |= - static_cast(AccessibleNodeInterface::SELECTION); - else if (!strcmp(iface, "Text")) - mSupportingIfaces |= - static_cast(AccessibleNodeInterface::TEXT); - else if (!strcmp(iface, "Value")) - mSupportingIfaces |= - static_cast(AccessibleNodeInterface::VALUE); - else if (!strcmp(iface, "Accessible")) - mSupportingIfaces |= - static_cast(AccessibleNodeInterface::ACCESSIBLE); - else if (!strcmp(iface, "Table")) - mSupportingIfaces |= - static_cast(AccessibleNodeInterface::TABLE); - else if (!strcmp(iface, "TableCell")) - mSupportingIfaces |= - static_cast(AccessibleNodeInterface::TABLECELL); - else - LOG_F(WARNING, "Not Supported interface found %s", iface); + if (mNode) { + GArray *ifaces = atspi_accessible_get_interfaces(mNode); + if (ifaces) { + for (unsigned int i = 0; i < ifaces->len; i++) { + char *iface = g_array_index(ifaces, char *, i); + if (!strcmp(iface, "Action")) + mSupportingIfaces |= + static_cast(AccessibleNodeInterface::ACTION); + else if (!strcmp(iface, "Collection")) + mSupportingIfaces |= + static_cast(AccessibleNodeInterface::COLLECTION); + else if (!strcmp(iface, "Component")) + mSupportingIfaces |= + static_cast(AccessibleNodeInterface::COMPONENT); + else if (!strcmp(iface, "Document")) + mSupportingIfaces |= + static_cast(AccessibleNodeInterface::DOCUMENT); + else if (!strcmp(iface, "EditableText")) + mSupportingIfaces |= + static_cast(AccessibleNodeInterface::EDITABLETEXT); + else if (!strcmp(iface, "Hypertext")) + mSupportingIfaces |= + static_cast(AccessibleNodeInterface::HYPERTEXT); + else if (!strcmp(iface, "Image")) + mSupportingIfaces |= + static_cast(AccessibleNodeInterface::IMAGE); + else if (!strcmp(iface, "Selection")) + mSupportingIfaces |= + static_cast(AccessibleNodeInterface::SELECTION); + else if (!strcmp(iface, "Text")) + mSupportingIfaces |= + static_cast(AccessibleNodeInterface::TEXT); + else if (!strcmp(iface, "Value")) + mSupportingIfaces |= + static_cast(AccessibleNodeInterface::VALUE); + else if (!strcmp(iface, "Accessible")) + mSupportingIfaces |= + static_cast(AccessibleNodeInterface::ACCESSIBLE); + else if (!strcmp(iface, "Table")) + mSupportingIfaces |= + static_cast(AccessibleNodeInterface::TABLE); + else if (!strcmp(iface, "TableCell")) + mSupportingIfaces |= + static_cast(AccessibleNodeInterface::TABLECELL); + else + LOG_F(WARNING, "Not Supported interface found %s", iface); - g_free(iface); + g_free(iface); + } + g_array_free(ifaces, FALSE); } - g_array_free(ifaces, FALSE); + this->refresh(); + } else { + LOG_F(INFO, "AtspiAccessibleNode Ctor : mNode is null"); } - this->refresh(); } AtspiAccessibleNode::~AtspiAccessibleNode() @@ -69,6 +73,7 @@ AtspiAccessibleNode::~AtspiAccessibleNode() int AtspiAccessibleNode::getChildCount() const { + if (!isValid()) return 0; int count = atspi_accessible_get_child_count(mNode, NULL); if (count <= 0) return 0; return count; @@ -76,6 +81,7 @@ int AtspiAccessibleNode::getChildCount() const std::shared_ptr AtspiAccessibleNode::getChildAt(int index) const { + if (!isValid()) std::make_shared(nullptr); LOG_SCOPE_F(INFO, "getChild @ %d from node(%p)", index, mNode); AtspiAccessible *rawChild = atspi_accessible_get_child_at_index(mNode, index, NULL); return std::make_shared(rawChild); @@ -94,12 +100,27 @@ std::vector> AtspiAccessibleNode::getChildren() std::shared_ptr AtspiAccessibleNode::getParent() const { + if (!isValid()) std::make_shared(nullptr); AtspiAccessible *rawParent = atspi_accessible_get_parent(mNode, NULL); return std::make_shared(rawParent); /* auto node = AccessibleNode::get(parent); if (parent) g_object_unref(parent); return node; */ } +bool AtspiAccessibleNode::isValid() const +{ + if (!mNode) return false; + + AtspiStateSet *st = atspi_accessible_get_state_set(mNode); + if (!st) return false; + if (atspi_state_set_contains(st, ATSPI_STATE_INVALID) || + atspi_state_set_contains(st, ATSPI_STATE_DEFUNCT)) { + g_object_unref(st); + return false; + } + g_object_unref(st); + return true; +} void* AtspiAccessibleNode::getRawHandler(void) const @@ -109,64 +130,71 @@ void* AtspiAccessibleNode::getRawHandler(void) const void AtspiAccessibleNode::refresh() { - gchar *rolename = atspi_accessible_get_role_name(mNode, NULL); - if (rolename) { - mRole = rolename; - g_free(rolename); - } -#ifdef TIZEN - gchar *uID = atspi_accessible_get_unique_id(mNode, NULL); - if (uID) { - mId = uID; - g_free(uID); - } -#else - mId = std::string{"N/A"}; -#endif - - gchar *name = atspi_accessible_get_name(mNode, NULL); - mText = name; - mPkg = name; - g_free(name); - - GHashTable *attributes = atspi_accessible_get_attributes(mNode, NULL); - char *t = (char*)g_hash_table_lookup(attributes, "type"); - char *s = (char*)g_hash_table_lookup(attributes, "style"); - char *a = (char*)g_hash_table_lookup(attributes, "automationId"); - - if (t) mType = std::string(t); - if (s) mStyle = std::string(s); - if (a) mAutomationId = std::string(a); + if (isValid()) { + gchar *rolename = atspi_accessible_get_role_name(mNode, NULL); + if (rolename) { + mRole = rolename; + g_free(rolename); + } + #ifdef TIZEN + gchar *uID = atspi_accessible_get_unique_id(mNode, NULL); + if (uID) { + mId = uID; + g_free(uID); + } + #else + mId = std::string{"N/A"}; + #endif - free(t); - free(s); - free(a); + gchar *name = atspi_accessible_get_name(mNode, NULL); + mText = name; + mPkg = name; + g_free(name); - g_hash_table_unref(attributes); + GHashTable *attributes = atspi_accessible_get_attributes(mNode, NULL); + if (attributes) { + char *t = (char*)g_hash_table_lookup(attributes, "type"); + char *s = (char*)g_hash_table_lookup(attributes, "style"); + char *a = (char*)g_hash_table_lookup(attributes, "automationId"); - AtspiStateSet *st = atspi_accessible_get_state_set(mNode); - GArray *states = atspi_state_set_get_states(st); + if (t) mType = std::string(t); + if (s) mStyle = std::string(s); + if (a) mAutomationId = std::string(a); - AtspiStateType stat; - for (unsigned int i = 0; states && (i < states->len); ++i) { - stat = g_array_index(states, AtspiStateType, i); - setFeatureProperty(stat); - } + free(t); + free(s); + free(a); - if (states) g_array_free(states, 0); - g_object_unref(st); + g_hash_table_unref(attributes); + } - AtspiComponent *component = atspi_accessible_get_component_iface(mNode); - if (component) { - AtspiRect *extent = atspi_component_get_extents( - component, ATSPI_COORD_TYPE_SCREEN, NULL); - if (extent) { - mBoundingBox = - Rect{extent->x, extent->y, extent->x + extent->width, - extent->y + extent->height}; - g_free(extent); + AtspiStateSet *st = atspi_accessible_get_state_set(mNode); + if (st) { + GArray *states = atspi_state_set_get_states(st); + if (states) { + AtspiStateType stat; + for (unsigned int i = 0; states && (i < states->len); ++i) { + stat = g_array_index(states, AtspiStateType, i); + setFeatureProperty(stat); + } + g_array_free(states, 0); + } + g_object_unref(st); + } + AtspiComponent *component = atspi_accessible_get_component_iface(mNode); + if (component) { + AtspiRect *extent = atspi_component_get_extents( + component, ATSPI_COORD_TYPE_SCREEN, NULL); + if (extent) { + mBoundingBox = + Rect{extent->x, extent->y, extent->x + extent->width, + extent->y + extent->height}; + g_free(extent); + } + g_object_unref(component); } - g_object_unref(component); + } else { + setFeatureProperty(ATSPI_STATE_INVALID); } } @@ -174,6 +202,7 @@ std::vector AtspiAccessibleNode::getActions() const { std::vector result{}; AtspiAction *action; + if (!isValid()) return result; action = atspi_accessible_get_action_iface(mNode); if (action) { @@ -194,7 +223,7 @@ std::vector AtspiAccessibleNode::getActions() const bool AtspiAccessibleNode::doAction(std::string actionName) { AtspiAction *action; - + if (!isValid()) return false; action = atspi_accessible_get_action_iface(mNode); if (action) { int a; @@ -219,6 +248,8 @@ bool AtspiAccessibleNode::doAction(std::string actionName) void AtspiAccessibleNode::setValue(std::string text) { + if (!isValid()) return; + AtspiEditableText *iface = atspi_accessible_get_editable_text(mNode); LOG_F(INFO,"set Value iface:%p obj:%p text:%s", iface, mNode, text.c_str() ); if (iface) {