Bug 1324044. Add fingerprinting resistance in GetSupportedNames in nsMimeTypeArray and nsPluginArray. r=qdot
authorBoris Zbarsky <bzbarsky@mit.edu>
Sat, 17 Dec 2016 00:25:52 -0500
changeset 450702 dcc7b0c683ce81ed762d1fe4ff396ea9caeb0bea
parent 450701 13f20e14bb7e7f149713f269f2fe711b99d3a91a
child 450703 6be7eb833b119bd37ffc641f9356617cfeeb22f2
push id38944
push userbmo:leftysolara@gmail.com
push dateSun, 18 Dec 2016 16:01:15 +0000
reviewersqdot
bugs1324044
milestone53.0a1
Bug 1324044. Add fingerprinting resistance in GetSupportedNames in nsMimeTypeArray and nsPluginArray. r=qdot
dom/base/nsMimeTypeArray.cpp
dom/base/nsMimeTypeArray.h
dom/base/nsPluginArray.cpp
dom/base/nsPluginArray.h
dom/bindings/Codegen.py
dom/bindings/Configuration.py
--- a/dom/base/nsMimeTypeArray.cpp
+++ b/dom/base/nsMimeTypeArray.cpp
@@ -147,18 +147,23 @@ nsMimeTypeArray::Length(CallerType aCall
   }
 
   EnsurePluginMimeTypes();
 
   return mMimeTypes.Length();
 }
 
 void
-nsMimeTypeArray::GetSupportedNames(nsTArray<nsString>& aRetval)
+nsMimeTypeArray::GetSupportedNames(nsTArray<nsString>& aRetval,
+                                   CallerType aCallerType)
 {
+  if (nsContentUtils::ResistFingerprinting(aCallerType)) {
+    return;
+  }
+
   EnsurePluginMimeTypes();
 
   for (uint32_t i = 0; i < mMimeTypes.Length(); ++i) {
     aRetval.AppendElement(mMimeTypes[i]->Type());
   }
 }
 
 void
--- a/dom/base/nsMimeTypeArray.h
+++ b/dom/base/nsMimeTypeArray.h
@@ -34,17 +34,18 @@ public:
   nsMimeType* Item(uint32_t index, mozilla::dom::CallerType aCallerType);
   nsMimeType* NamedItem(const nsAString& name,
                         mozilla::dom::CallerType aCallerType);
   nsMimeType* IndexedGetter(uint32_t index, bool &found,
                             mozilla::dom::CallerType aCallerType);
   nsMimeType* NamedGetter(const nsAString& name, bool &found,
                           mozilla::dom::CallerType aCallerType);
   uint32_t Length(mozilla::dom::CallerType aCallerType);
-  void GetSupportedNames(nsTArray<nsString>& retval);
+  void GetSupportedNames(nsTArray<nsString>& retval,
+                         mozilla::dom::CallerType aCallerType);
 
 protected:
   virtual ~nsMimeTypeArray();
 
   void EnsurePluginMimeTypes();
   void Clear();
 
   nsCOMPtr<nsPIDOMWindowInner> mWindow;
--- a/dom/base/nsPluginArray.cpp
+++ b/dom/base/nsPluginArray.cpp
@@ -276,21 +276,22 @@ nsPluginArray::Length(CallerType aCaller
   }
 
   EnsurePlugins();
 
   return mPlugins.Length();
 }
 
 void
-nsPluginArray::GetSupportedNames(nsTArray<nsString>& aRetval)
+nsPluginArray::GetSupportedNames(nsTArray<nsString>& aRetval,
+                                 CallerType aCallerType)
 {
   aRetval.Clear();
 
-  if (!AllowPlugins()) {
+  if (!AllowPlugins() || nsContentUtils::ResistFingerprinting(aCallerType)) {
     return;
   }
 
   for (uint32_t i = 0; i < mPlugins.Length(); ++i) {
     nsAutoString pluginName;
     mPlugins[i]->GetName(pluginName);
 
     aRetval.AppendElement(pluginName);
--- a/dom/base/nsPluginArray.h
+++ b/dom/base/nsPluginArray.h
@@ -52,17 +52,18 @@ public:
   nsPluginElement* NamedItem(const nsAString& aName,
                              mozilla::dom::CallerType aCallerType);
   void Refresh(bool aReloadDocuments);
   nsPluginElement* IndexedGetter(uint32_t aIndex, bool &aFound,
                                  mozilla::dom::CallerType aCallerType);
   nsPluginElement* NamedGetter(const nsAString& aName, bool &aFound,
                                mozilla::dom::CallerType aCallerType);
   uint32_t Length(mozilla::dom::CallerType aCallerType);
-  void GetSupportedNames(nsTArray<nsString>& aRetval);
+  void GetSupportedNames(nsTArray<nsString>& aRetval,
+                         mozilla::dom::CallerType aCallerType);
 
 private:
   virtual ~nsPluginArray();
 
   bool AllowPlugins() const;
   void EnsurePlugins();
 
   nsCOMPtr<nsPIDOMWindowInner> mWindow;
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -11623,24 +11623,31 @@ class CGDOMJSProxyHandler_ownPropNames(C
         else:
             addIndices = ""
 
         if self.descriptor.supportsNamedProperties():
             if self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
                 shadow = "!isXray"
             else:
                 shadow = "false"
+
+            if self.descriptor.supportedNamesNeedCallerType():
+                callerType = ", " + callerTypeGetterForDescriptor(self.descriptor)
+            else:
+                callerType = ""
+
             addNames = fill(
                 """
                 nsTArray<nsString> names;
-                UnwrapProxy(proxy)->GetSupportedNames(names);
+                UnwrapProxy(proxy)->GetSupportedNames(names${callerType});
                 if (!AppendNamedPropertyIds(cx, proxy, names, ${shadow}, props)) {
                   return false;
                 }
                 """,
+                callerType=callerType,
                 shadow=shadow)
             if not self.descriptor.namedPropertiesEnumerable:
                 addNames = CGIfWrapper(CGGeneric(addNames),
                                        "flags & JSITER_HIDDEN").define()
             addNames = "\n" + addNames
         else:
             addNames = ""
 
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -618,16 +618,26 @@ class Descriptor(DescriptorProvider):
         """
         assert self.supportsIndexedProperties()
         indexedGetter = self.operations['IndexedGetter']
         return indexedGetter.getExtendedAttribute("NeedsCallerType")
 
     def supportsNamedProperties(self):
         return self.operations['NamedGetter'] is not None
 
+    def supportedNamesNeedCallerType(self):
+        """
+        Determine whether our GetSupportedNames call needs a caller type.  The
+        idea is that if your named getter needs a caller type, then so does
+        GetSupportedNames.
+        """
+        assert self.supportsNamedProperties()
+        namedGetter = self.operations['NamedGetter']
+        return namedGetter.getExtendedAttribute("NeedsCallerType")
+
     def hasNonOrdinaryGetPrototypeOf(self):
         return self.interface.getExtendedAttribute("NonOrdinaryGetPrototypeOf")
 
     def needsHeaderInclude(self):
         """
         An interface doesn't need a header file if it is not concrete, not
         pref-controlled, has no prototype object, has no static methods or
         attributes and has no parent.  The parent matters because we assert