Bug 1086684 - Stash the full path for file inputs to avoid doing IPC at inopportune times. r=ehsan/bent/gps
authorBlake Kaplan <mrbkap@gmail.com>
Fri, 27 Mar 2015 13:12:37 -0700
changeset 265141 6802c30854387e14973d38114902396362fd2124
parent 265140 7264dc6085845a0018bbbdbb00b90cbcd538b2de
child 265142 20d97f735cde591c6561f1eb727c5d470c4a7080
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan, bent, gps
bugs1086684
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1086684 - Stash the full path for file inputs to avoid doing IPC at inopportune times. r=ehsan/bent/gps
configure.in
dom/html/HTMLInputElement.cpp
dom/html/HTMLInputElement.h
dom/ipc/moz.build
--- a/configure.in
+++ b/configure.in
@@ -5699,22 +5699,28 @@ dnl ====================================
 dnl Permissions System
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(permissions,
 [  --disable-permissions   Disable permissions (popup and cookie blocking)],
     MOZ_PERMISSIONS=,
     MOZ_PERMISSIONS=1
 )
 
+AC_SUBST(MOZ_PERMISSIONS)
+if test -n "$MOZ_PERMISSIONS"; then
+    AC_DEFINE(MOZ_PERMISSIONS)
+fi
+
 dnl ========================================================
 dnl Child permissions, currently only used for b2g
 dnl ========================================================
 if test -n "$MOZ_B2G"; then
     if test -n "$MOZ_PERMISSIONS"; then
         MOZ_CHILD_PERMISSIONS=1
+        AC_DEFINE(MOZ_CHILD_PERMISSIONS)
     else
         AC_MSG_ERROR([You need to enable MOZ_PERMISSIONS for MOZ_CHILD_PERMISSIONS])
     fi
 fi
 AC_SUBST(MOZ_CHILD_PERMISSIONS)
 
 dnl ========================================================
 dnl NegotiateAuth
@@ -8424,17 +8430,16 @@ AC_SUBST(RCFLAGS)
 AC_SUBST(MC)
 AC_SUBST(WINDRES)
 AC_SUBST(IMPLIB)
 AC_SUBST(FILTER)
 AC_SUBST(BIN_FLAGS)
 AC_SUBST(MOZ_WIDGET_TOOLKIT)
 AC_SUBST(MOZ_UPDATE_XTERM)
 AC_SUBST(MOZ_AUTH_EXTENSION)
-AC_SUBST(MOZ_PERMISSIONS)
 AC_SUBST(MOZ_PREF_EXTENSIONS)
 AC_SUBST(MOZ_DEBUG)
 AC_SUBST(MOZ_DEBUG_SYMBOLS)
 AC_SUBST(MOZ_DEBUG_ENABLE_DEFS)
 AC_SUBST(MOZ_DEBUG_DISABLE_DEFS)
 AC_SUBST(MOZ_DEBUG_LDFLAGS)
 AC_SUBST(WARNINGS_AS_ERRORS)
 AC_SUBST(MOZ_EXTENSIONS)
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -1,9 +1,10 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 sts=2 et tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLInputElement.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/AsyncEventDispatcher.h"
@@ -1687,22 +1688,28 @@ HTMLInputElement::GetValueInternal(nsASt
         mInputData.mState->GetValue(aValue, true);
       } else {
         aValue.Assign(mInputData.mValue);
       }
       return NS_OK;
 
     case VALUE_MODE_FILENAME:
       if (nsContentUtils::IsCallerChrome()) {
+#ifndef MOZ_CHILD_PERMISSIONS
+        aValue.Assign(mFirstFilePath);
+#else
+        // XXX We'd love to assert that this can't happen, but some mochitests
+        // use SpecialPowers to circumvent our more sane security model.
         if (!mFiles.IsEmpty()) {
           return mFiles[0]->GetMozFullPath(aValue);
         }
         else {
           aValue.Truncate();
         }
+#endif
       } else {
         // Just return the leaf name
         if (mFiles.IsEmpty() || NS_FAILED(mFiles[0]->GetName(aValue))) {
           aValue.Truncate();
         }
       }
 
       return NS_OK;
@@ -2642,16 +2649,29 @@ HTMLInputElement::AfterSetFiles(bool aSe
   // new value.  We just want the display to update as needed.
   nsIFormControlFrame* formControlFrame = GetFormControlFrame(false);
   if (formControlFrame) {
     nsAutoString readableValue;
     GetDisplayFileName(readableValue);
     formControlFrame->SetFormProperty(nsGkAtoms::value, readableValue);
   }
 
+#ifndef MOZ_CHILD_PERMISSIONS
+  // Grab the full path here for any chrome callers who access our .value via a
+  // CPOW. This path won't be called from a CPOW meaning the potential sync IPC
+  // call under GetMozFullPath won't be rejected for not being urgent.
+  // XXX Protected by the ifndef because the blob code doesn't allow us to send
+  // this message in b2g.
+  if (mFiles.IsEmpty()) {
+    mFirstFilePath.Truncate();
+  } else {
+    mFiles[0]->GetMozFullPath(mFirstFilePath);
+  }
+#endif
+
   UpdateFileList();
 
   if (aSetValueChanged) {
     SetValueChanged(true);
   }
 
   UpdateAllValidityStates(true);
 }
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -1249,28 +1249,36 @@ protected:
      * The current value of the input if it has been changed from the default
      */
     char16_t*               mValue;
     /**
      * The state of the text editor associated with the text/password input
      */
     nsTextEditorState*       mState;
   } mInputData;
+
   /**
    * The value of the input if it is a file input. This is the list of filenames
    * used when uploading a file. It is vital that this is kept separate from
    * mValue so that it won't be possible to 'leak' the value from a text-input
    * to a file-input. Additionally, the logic for this value is kept as simple
    * as possible to avoid accidental errors where the wrong filename is used.
    * Therefor the list of filenames is always owned by this member, never by
    * the frame. Whenever the frame wants to change the filename it has to call
    * SetFileNames to update this member.
    */
   nsTArray<nsRefPtr<File>> mFiles;
 
+#ifndef MOZ_CHILD_PERMISSIONS
+  /**
+   * Hack for bug 1086684: Stash the .value when we're a file picker.
+   */
+  nsString mFirstFilePath;
+#endif
+
   nsRefPtr<FileList>  mFileList;
 
   nsRefPtr<DirPickerFileListBuilderTask> mDirPickerFileListBuilderTask;
 
   nsString mStaticDocFileList;
   
   /** 
    * The value of the input element when first initialized and it is updated
--- a/dom/ipc/moz.build
+++ b/dom/ipc/moz.build
@@ -143,19 +143,15 @@ LOCAL_INCLUDES += [
 DEFINES['BIN_SUFFIX'] = '"%s"' % CONFIG['BIN_SUFFIX']
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gonk', 'qt'):
     DEFINES['MOZ_ENABLE_FREETYPE'] = True
 
 if CONFIG['MOZ_TOOLKIT_SEARCH']:
     DEFINES['MOZ_TOOLKIT_SEARCH'] = True
 
-for var in ('MOZ_PERMISSIONS', 'MOZ_CHILD_PERMISSIONS'):
-    if CONFIG[var]:
-        DEFINES[var] = True
-
 JAR_MANIFESTS += ['jar.mn']
 
 BROWSER_CHROME_MANIFESTS += ['tests/browser.ini']
 MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini']
 MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
 
 CXXFLAGS += CONFIG['TK_CFLAGS']