accessible/src/windows/sdn/sdnAccessible.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=2 et sw=2 tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "sdnAccessible-inl.h"
     8 #include "ISimpleDOMNode_i.c"
    10 #include "DocAccessibleWrap.h"
    12 #include "nsAttrName.h"
    13 #include "nsCoreUtils.h"
    14 #include "nsIAccessibleTypes.h"
    15 #include "nsIDOMHTMLElement.h"
    16 #include "nsIDOMCSSStyleDeclaration.h"
    17 #include "nsNameSpaceManager.h"
    18 #include "nsServiceManagerUtils.h"
    19 #include "nsWinUtils.h"
    21 #include "nsAutoPtr.h"
    23 #include "mozilla/dom/Element.h"
    25 using namespace mozilla;
    26 using namespace mozilla::a11y;
    28 STDMETHODIMP
    29 sdnAccessible::QueryInterface(REFIID aREFIID, void** aInstancePtr)
    30 {
    31   A11Y_TRYBLOCK_BEGIN
    33   if (!aInstancePtr)
    34     return E_FAIL;
    35   *aInstancePtr = nullptr;
    37   if (aREFIID == IID_ISimpleDOMNode) {
    38     *aInstancePtr = static_cast<ISimpleDOMNode*>(this);
    39     AddRef();
    40     return S_OK;
    41   }
    43   AccessibleWrap* accessible = static_cast<AccessibleWrap*>(GetAccessible());
    44   if (accessible)
    45     return accessible->QueryInterface(aREFIID, aInstancePtr);
    47   // IUnknown* is the canonical one if and only if this accessible doesn't have
    48   // an accessible.
    49   if (aREFIID == IID_IUnknown) {
    50     *aInstancePtr = static_cast<ISimpleDOMNode*>(this);
    51     AddRef();
    52     return S_OK;
    53   }
    55   return E_NOINTERFACE;
    57   A11Y_TRYBLOCK_END
    58 }
    60 STDMETHODIMP
    61 sdnAccessible::get_nodeInfo(BSTR __RPC_FAR* aNodeName,
    62                             short __RPC_FAR* aNameSpaceID,
    63                             BSTR __RPC_FAR* aNodeValue,
    64                             unsigned int __RPC_FAR* aNumChildren,
    65                             unsigned int __RPC_FAR* aUniqueID,
    66                             unsigned short __RPC_FAR* aNodeType)
    67 {
    68   A11Y_TRYBLOCK_BEGIN
    70   if (!aNodeName || !aNameSpaceID || !aNodeValue || !aNumChildren ||
    71       !aUniqueID || !aNodeType)
    72     return E_INVALIDARG;
    74   *aNodeName = nullptr;
    75   *aNameSpaceID = 0;
    76   *aNodeValue = nullptr;
    77   *aNumChildren = 0;
    78   *aUniqueID = 0;
    79   *aNodeType = 0;
    81   if (IsDefunct())
    82     return CO_E_OBJNOTCONNECTED;
    84   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mNode));
    86   uint16_t nodeType = 0;
    87   DOMNode->GetNodeType(&nodeType);
    88   *aNodeType = static_cast<unsigned short>(nodeType);
    90   if (*aNodeType !=  NODETYPE_TEXT) {
    91     nsAutoString nodeName;
    92     DOMNode->GetNodeName(nodeName);
    93     *aNodeName = ::SysAllocString(nodeName.get());
    94   }
    96   nsAutoString nodeValue;
    97   DOMNode->GetNodeValue(nodeValue);
    98   *aNodeValue = ::SysAllocString(nodeValue.get());
   100   *aNameSpaceID = mNode->IsNodeOfType(nsINode::eCONTENT) ?
   101     static_cast<short>(mNode->AsContent()->GetNameSpaceID()) : 0;
   103   // This is a unique ID for every content node. The 3rd party accessibility
   104   // application can compare this to the childID we return for events such as
   105   // focus events, to correlate back to data nodes in their internal object
   106   // model.
   107   Accessible* accessible = GetAccessible();
   108   *aUniqueID = - NS_PTR_TO_INT32(accessible ? accessible->UniqueID() :
   109                                               static_cast<void*>(this));
   111   *aNumChildren = mNode->GetChildCount();
   113   return S_OK;
   115   A11Y_TRYBLOCK_END
   116 }
   118 STDMETHODIMP
   119 sdnAccessible::get_attributes(unsigned  short aMaxAttribs,
   120                               BSTR __RPC_FAR* aAttribNames,
   121                               short __RPC_FAR* aNameSpaceIDs,
   122                               BSTR __RPC_FAR* aAttribValues,
   123                               unsigned short __RPC_FAR* aNumAttribs)
   124 {
   125   A11Y_TRYBLOCK_BEGIN
   127   if (!aAttribNames || !aNameSpaceIDs || !aAttribValues || !aNumAttribs)
   128     return E_INVALIDARG;
   130   *aNumAttribs = 0;
   132   if (IsDefunct())
   133     return CO_E_OBJNOTCONNECTED;
   135   if (!mNode->IsElement())
   136     return S_FALSE;
   138   dom::Element* elm = mNode->AsElement();
   139   uint32_t numAttribs = elm->GetAttrCount();
   140   if (numAttribs > aMaxAttribs)
   141     numAttribs = aMaxAttribs;
   143   *aNumAttribs = static_cast<unsigned short>(numAttribs);
   145   for (uint32_t index = 0; index < numAttribs; index++) {
   146     aNameSpaceIDs[index] = 0;
   147     aAttribValues[index] = aAttribNames[index] = nullptr;
   148     nsAutoString attributeValue;
   150     const nsAttrName* name = elm->GetAttrNameAt(index);
   151     aNameSpaceIDs[index] = static_cast<short>(name->NamespaceID());
   152     aAttribNames[index] = ::SysAllocString(name->LocalName()->GetUTF16String());
   153     elm->GetAttr(name->NamespaceID(), name->LocalName(), attributeValue);
   154     aAttribValues[index] = ::SysAllocString(attributeValue.get());
   155   }
   157   return S_OK;
   159   A11Y_TRYBLOCK_END
   160 }
   162 STDMETHODIMP
   163 sdnAccessible::get_attributesForNames(unsigned short aMaxAttribs,
   164                                       BSTR __RPC_FAR* aAttribNames,
   165                                       short __RPC_FAR* aNameSpaceID,
   166                                       BSTR __RPC_FAR* aAttribValues)
   167 {
   168   A11Y_TRYBLOCK_BEGIN
   170   if (!aAttribNames || !aNameSpaceID || !aAttribValues)
   171     return E_INVALIDARG;
   173   if (IsDefunct())
   174     return CO_E_OBJNOTCONNECTED;
   176   if (!mNode->IsElement())
   177     return S_FALSE;
   179   nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(mNode));
   180   nsNameSpaceManager* nameSpaceManager = nsNameSpaceManager::GetInstance();
   182   int32_t index = 0;
   183   for (index = 0; index < aMaxAttribs; index++) {
   184     aAttribValues[index] = nullptr;
   185     if (aAttribNames[index]) {
   186       nsAutoString attributeValue, nameSpaceURI;
   187       nsAutoString attributeName(nsDependentString(
   188         static_cast<const wchar_t*>(aAttribNames[index])));
   190       nsresult rv = NS_OK;
   191       if (aNameSpaceID[index]>0 &&
   192         NS_SUCCEEDED(nameSpaceManager->GetNameSpaceURI(aNameSpaceID[index],
   193                                                        nameSpaceURI))) {
   194           rv = domElement->GetAttributeNS(nameSpaceURI, attributeName,
   195                                           attributeValue);
   196       } else {
   197         rv = domElement->GetAttribute(attributeName, attributeValue);
   198       }
   200       if (NS_SUCCEEDED(rv))
   201         aAttribValues[index] = ::SysAllocString(attributeValue.get());
   202     }
   203   }
   205   return S_OK;
   207   A11Y_TRYBLOCK_END
   208 }
   210 STDMETHODIMP
   211 sdnAccessible::get_computedStyle(unsigned short aMaxStyleProperties,
   212                                  boolean aUseAlternateView,
   213                                  BSTR __RPC_FAR* aStyleProperties,
   214                                  BSTR __RPC_FAR* aStyleValues,
   215                                  unsigned short __RPC_FAR* aNumStyleProperties)
   216 {
   217   A11Y_TRYBLOCK_BEGIN
   219   if (!aStyleProperties || aStyleValues || !aNumStyleProperties)
   220     return E_INVALIDARG;
   222   if (IsDefunct())
   223     return CO_E_OBJNOTCONNECTED;
   225   *aNumStyleProperties = 0;
   227   if (mNode->IsNodeOfType(nsINode::eDOCUMENT))
   228     return S_FALSE;
   230   nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl =
   231     nsWinUtils::GetComputedStyleDeclaration(mNode->AsContent());
   232   NS_ENSURE_TRUE(cssDecl, E_FAIL);
   234   uint32_t length = 0;
   235   cssDecl->GetLength(&length);
   237   uint32_t index = 0, realIndex = 0;
   238   for (index = realIndex = 0; index < length && realIndex < aMaxStyleProperties;
   239        index ++) {
   240     nsAutoString property, value;
   242     // Ignore -moz-* properties.
   243     if (NS_SUCCEEDED(cssDecl->Item(index, property)) && property.CharAt(0) != '-')
   244       cssDecl->GetPropertyValue(property, value);  // Get property value
   246     if (!value.IsEmpty()) {
   247       aStyleProperties[realIndex] = ::SysAllocString(property.get());
   248       aStyleValues[realIndex] = ::SysAllocString(value.get());
   249       ++realIndex;
   250     }
   251   }
   253   *aNumStyleProperties = static_cast<unsigned short>(realIndex);
   255   return S_OK;
   257   A11Y_TRYBLOCK_END
   258 }
   260 STDMETHODIMP
   261 sdnAccessible::get_computedStyleForProperties(unsigned short aNumStyleProperties,
   262                                               boolean aUseAlternateView,
   263                                               BSTR __RPC_FAR* aStyleProperties,
   264                                               BSTR __RPC_FAR* aStyleValues)
   265 {
   266   A11Y_TRYBLOCK_BEGIN
   268   if (!aStyleProperties || !aStyleValues)
   269     return E_INVALIDARG;
   271   if (IsDefunct())
   272     return CO_E_OBJNOTCONNECTED;
   274   if (mNode->IsNodeOfType(nsINode::eDOCUMENT))
   275     return S_FALSE;
   277   nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl =
   278     nsWinUtils::GetComputedStyleDeclaration(mNode->AsContent());
   279   NS_ENSURE_TRUE(cssDecl, E_FAIL);
   281   uint32_t index = 0;
   282   for (index = 0; index < aNumStyleProperties; index++) {
   283     nsAutoString value;
   284     if (aStyleProperties[index])
   285       cssDecl->GetPropertyValue(nsDependentString(aStyleProperties[index]), value);  // Get property value
   286     aStyleValues[index] = ::SysAllocString(value.get());
   287   }
   289   return S_OK;
   291   A11Y_TRYBLOCK_END
   292 }
   294 STDMETHODIMP
   295 sdnAccessible::scrollTo(boolean aScrollTopLeft)
   296 {
   297   A11Y_TRYBLOCK_BEGIN
   299   DocAccessible* document = GetDocument();
   300   if (!document) // that's IsDefunct check
   301     return CO_E_OBJNOTCONNECTED;
   303   if (!mNode->IsContent())
   304     return S_FALSE;
   306   uint32_t scrollType =
   307     aScrollTopLeft ? nsIAccessibleScrollType::SCROLL_TYPE_TOP_LEFT :
   308                      nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_RIGHT;
   310   nsCoreUtils::ScrollTo(document->PresShell(), mNode->AsContent(), scrollType);
   311   return S_OK;
   313   A11Y_TRYBLOCK_END
   314 }
   316 STDMETHODIMP
   317 sdnAccessible::get_parentNode(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
   318 {
   319   A11Y_TRYBLOCK_BEGIN
   321   if (!aNode)
   322     return E_INVALIDARG;
   323   *aNode = nullptr;
   325   if (IsDefunct())
   326     return CO_E_OBJNOTCONNECTED;
   328   nsINode* resultNode = mNode->GetParentNode();
   329   if (resultNode) {
   330     *aNode = static_cast<ISimpleDOMNode*>(new sdnAccessible(resultNode));
   331     (*aNode)->AddRef();
   332   }
   334   return S_OK;
   336   A11Y_TRYBLOCK_END
   337 }
   339 STDMETHODIMP
   340 sdnAccessible::get_firstChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
   341 {
   342   A11Y_TRYBLOCK_BEGIN
   344   if (!aNode)
   345     return E_INVALIDARG;
   346   *aNode = nullptr;
   348   if (IsDefunct())
   349     return CO_E_OBJNOTCONNECTED;
   351   nsINode* resultNode = mNode->GetFirstChild();
   352   if (resultNode) {
   353     *aNode = static_cast<ISimpleDOMNode*>(new sdnAccessible(resultNode));
   354     (*aNode)->AddRef();
   355   }
   357   return S_OK;
   359   A11Y_TRYBLOCK_END
   360 }
   362 STDMETHODIMP
   363 sdnAccessible::get_lastChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
   364 {
   365   A11Y_TRYBLOCK_BEGIN
   367   if (!aNode)
   368     return E_INVALIDARG;
   369   *aNode = nullptr;
   371   if (IsDefunct())
   372     return CO_E_OBJNOTCONNECTED;
   374   nsINode* resultNode = mNode->GetLastChild();
   375   if (resultNode) {
   376     *aNode = static_cast<ISimpleDOMNode*>(new sdnAccessible(resultNode));
   377     (*aNode)->AddRef();
   378   }
   380   return S_OK;
   382   A11Y_TRYBLOCK_END
   383 }
   385 STDMETHODIMP
   386 sdnAccessible::get_previousSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
   387 {
   388   A11Y_TRYBLOCK_BEGIN
   390   if (!aNode)
   391     return E_INVALIDARG;
   392   *aNode = nullptr;
   394   if (IsDefunct())
   395     return CO_E_OBJNOTCONNECTED;
   397   nsINode* resultNode = mNode->GetPreviousSibling();
   398   if (resultNode) {
   399     *aNode = static_cast<ISimpleDOMNode*>(new sdnAccessible(resultNode));
   400     (*aNode)->AddRef();
   401   }
   403   return S_OK;
   405   A11Y_TRYBLOCK_END
   406 }
   408 STDMETHODIMP
   409 sdnAccessible::get_nextSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
   410 {
   411   A11Y_TRYBLOCK_BEGIN
   413   if (!aNode)
   414     return E_INVALIDARG;
   415   *aNode = nullptr;
   417   if (IsDefunct())
   418     return CO_E_OBJNOTCONNECTED;
   420   nsINode* resultNode = mNode->GetNextSibling();
   421   if (resultNode) {
   422     *aNode = static_cast<ISimpleDOMNode*>(new sdnAccessible(resultNode));
   423     (*aNode)->AddRef();
   424   }
   426   return S_OK;
   428   A11Y_TRYBLOCK_END
   429 }
   431 STDMETHODIMP
   432 sdnAccessible::get_childAt(unsigned aChildIndex,
   433                            ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
   434 {
   435   A11Y_TRYBLOCK_BEGIN
   437   if (!aNode)
   438     return E_INVALIDARG;
   439   *aNode = nullptr;
   441   if (IsDefunct())
   442     return CO_E_OBJNOTCONNECTED;
   444   nsINode* resultNode = mNode->GetChildAt(aChildIndex);
   445   if (resultNode) {
   446     *aNode = static_cast<ISimpleDOMNode*>(new sdnAccessible(resultNode));
   447     (*aNode)->AddRef();
   448   }
   451   return S_OK;
   453   A11Y_TRYBLOCK_END
   454 }
   456 STDMETHODIMP
   457 sdnAccessible::get_innerHTML(BSTR __RPC_FAR* aInnerHTML)
   458 {
   459   A11Y_TRYBLOCK_BEGIN
   461   if (!aInnerHTML)
   462     return E_INVALIDARG;
   463   *aInnerHTML = nullptr;
   465   if (IsDefunct())
   466     return CO_E_OBJNOTCONNECTED;
   468   if (!mNode->IsElement())
   469     return S_FALSE;
   471   nsAutoString innerHTML;
   472   mNode->AsElement()->GetInnerHTML(innerHTML);
   473   if (innerHTML.IsEmpty())
   474     return S_FALSE;
   476   *aInnerHTML = ::SysAllocStringLen(innerHTML.get(), innerHTML.Length());
   477   if (!*aInnerHTML)
   478     return E_OUTOFMEMORY;
   480   return S_OK;
   482   A11Y_TRYBLOCK_END
   483 }
   485 STDMETHODIMP
   486 sdnAccessible::get_localInterface(void __RPC_FAR *__RPC_FAR* aLocalInterface)
   487 {
   488   A11Y_TRYBLOCK_BEGIN
   490   if (!aLocalInterface)
   491     return E_INVALIDARG;
   492   *aLocalInterface = nullptr;
   494   if (IsDefunct())
   495     return CO_E_OBJNOTCONNECTED;
   497   *aLocalInterface = this;
   498   AddRef();
   500   return S_OK;
   502   A11Y_TRYBLOCK_END
   503 }
   505 STDMETHODIMP
   506 sdnAccessible::get_language(BSTR __RPC_FAR* aLanguage)
   507 {
   508   A11Y_TRYBLOCK_BEGIN
   510   if (!aLanguage)
   511     return E_INVALIDARG;
   512   *aLanguage = nullptr;
   514   if (IsDefunct())
   515     return CO_E_OBJNOTCONNECTED;
   517   nsAutoString language;
   518   if (mNode->IsContent())
   519     nsCoreUtils::GetLanguageFor(mNode->AsContent(), nullptr, language);
   520   if (language.IsEmpty()) { // Nothing found, so use document's language
   521     mNode->OwnerDoc()->GetHeaderData(nsGkAtoms::headerContentLanguage,
   522                                      language);
   523   }
   525   if (language.IsEmpty())
   526     return S_FALSE;
   528   *aLanguage = ::SysAllocStringLen(language.get(), language.Length());
   529   if (!*aLanguage)
   530    return E_OUTOFMEMORY;
   532   return S_OK;
   534   A11Y_TRYBLOCK_END
   535 }

mercurial