Jelajahi Sumber

Fix ZF-11921: Race condition in plugin loader include file cache

This fixes the race condition described at:
http://framework.zend.com/issues/browse/ZF-11921

For the race to disappear each and every line is made completely independent from the others. This is the reason why every line includes its own php open and close tag, and no file_get_content() is made, and the file is opened in append only mode.

To prevent the insertion of duplicates lines, a fast non blocking lock is made and kept until the end of the request, thus the static $h.

Tested on a highly concurrent server without a problem.
Nicolas Grekas 12 tahun lalu
induk
melakukan
1688f3d00b
1 mengubah file dengan 11 tambahan dan 7 penghapusan
  1. 11 7
      library/Zend/Loader/PluginLoader.php

+ 11 - 7
library/Zend/Loader/PluginLoader.php

@@ -477,14 +477,18 @@ class Zend_Loader_PluginLoader implements Zend_Loader_PluginLoader_Interface
      */
      */
     protected static function _appendIncFile($incFile)
     protected static function _appendIncFile($incFile)
     {
     {
-        if (!file_exists(self::$_includeFileCache)) {
-            $file = '<?php';
-        } else {
-            $file = file_get_contents(self::$_includeFileCache);
+        static $h = null;
+
+        if (null === $h) {
+            $h = fopen(self::$_includeFileCache, 'ab');
+            if (!flock($h, LOCK_EX | LOCK_NB, $wb) || $wb) {
+                $h = false;
+            }
         }
         }
-        if (!strstr($file, $incFile)) {
-            $file .= "\ninclude_once '$incFile';";
-            file_put_contents(self::$_includeFileCache, $file);
+
+        if (false !== $h) {
+            $line = "<?php include_once '$incFile'?>\n";
+            fwrite($h, $line, strlen($line));
         }
         }
     }
     }
 }
 }