Bug 782231 - Do not automatically reopen a DirectoryIterator that is closed before being used on Windows. r=yoric
authorDavid Rajchenbach-Teller <dteller@mozilla.com>
Fri, 21 Sep 2012 23:36:15 -0400
changeset 107795 a1a658f7c1d62e63dd394699dd484c26884053d5
parent 107794 6ceb3039c0a8322194339a75abd85cc481e4c77f
child 107796 11ca43377445f5c2d7d8843bd317e3a04bebbaa9
push id23509
push userryanvm@gmail.com
push dateSat, 22 Sep 2012 12:28:38 +0000
treeherdermozilla-central@b461a7cd250e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyoric
bugs782231
milestone18.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 782231 - Do not automatically reopen a DirectoryIterator that is closed before being used on Windows. r=yoric
toolkit/components/osfile/osfile_win_front.jsm
--- a/toolkit/components/osfile/osfile_win_front.jsm
+++ b/toolkit/components/osfile/osfile_win_front.jsm
@@ -484,25 +484,32 @@
        if (options && options.winPattern) {
          this._pattern = path + "\\" + options.winPattern;
        } else {
          this._pattern = path + "\\*";
        }
        this._handle = null;
        this._path = path;
        this._started = false;
+       this._closed = false;
      };
      File.DirectoryIterator.prototype = Object.create(exports.OS.Shared.AbstractFile.AbstractIterator.prototype);
 
        /**
         * Fetch the next entry in the directory.
         *
         * @return null If we have reached the end of the directory.
         */
      File.DirectoryIterator.prototype._next = function _next() {
+        // Bailout if the iterator is closed. Note that this may
+        // happen even before it is fully initialized.
+        if (this._closed) {
+          return null;
+        }
+
          // Iterator is not fully initialized yet. Finish
          // initialization.
          if (!this._started) {
             this._started = true;
             this._handle = WinFile.FindFirstFile(this._pattern, gFindDataPtr);
             if (this._handle == null) {
               let error = ctypes.winLastError;
               if (error == Const.ERROR_FILE_NOT_FOUND) {
@@ -510,21 +517,16 @@
                 return null;
               } else {
                 throw new File.Error("iter (FindFirstFile)", error);
               }
             }
             return gFindData;
          }
 
-         // We have closed this iterator already.
-         if (!this._handle) {
-           return null;
-         }
-
          if (WinFile.FindNextFile(this._handle, gFindDataPtr)) {
            return gFindData;
          } else {
            let error = ctypes.winLastError;
            this.close();
            if (error == Const.ERROR_NO_MORE_FILES) {
               return null;
            } else {
@@ -550,24 +552,31 @@
            let name = entry.cFileName.readString();
            if (name == "." || name == "..") {
              continue;
            }
            return new File.DirectoryIterator.Entry(entry, this._path);
          }
          throw StopIteration;
      };
+
      File.DirectoryIterator.prototype.close = function close() {
-       if (!this._handle) {
+       if (this._closed) {
          return;
        }
-       throw_on_zero("FindClose",
-         WinFile.FindClose(this._handle));
-       this._handle = null;
+       this._closed = true;
+       if (this._handle) {
+         // We might not have a handle if the iterator is closed
+         // before being used.
+         throw_on_zero("FindClose",
+           WinFile.FindClose(this._handle));
+         this._handle = null;
+       }
      };
+
      File.DirectoryIterator.Entry = function Entry(win_entry, parent) {
        // Copy the relevant part of |win_entry| to ensure that
        // our data is not overwritten prematurely.
        if (!win_entry.dwFileAttributes) {
          throw new TypeError();
        }
        this._dwFileAttributes = win_entry.dwFileAttributes;
        this._name = win_entry.cFileName.readString();