OSDN Git Service

MEDIA::isValidCollection()
[nucleus-jp/nucleus-jp-ancient.git] / utf8 / nucleus / libs / MEDIA.php
index 12d5b54..7347af1 100755 (executable)
@@ -99,17 +99,30 @@ class MEDIA {
          * checks if a collection exists with the given name, and if it's
          * allowed for the currently logged in member to upload files to it
          */
          * checks if a collection exists with the given name, and if it's
          * allowed for the currently logged in member to upload files to it
          */
-       function isValidCollection($collectionName) {
-               global $member, $DIR_MEDIA;
-
-               // private collections only accept uploads from their owners
-               if (is_numeric($collectionName))
-                       return ($member->getID() == $collectionName);
-
-               // other collections should exists and be writable
-               $collectionDir = $DIR_MEDIA . $collectionName;
-               return (@is_dir($collectionDir) || @is_writable($collectionDir));
-       }
+       function isValidCollection($collectionName) {\r
+               global $member, $DIR_MEDIA;\r
+\r
+               // allow creating new private directory\r
+               if (preg_match('#^[0-9]+[/\\\\]?$#',$collectionName))\r
+                       return ((int)$member->getID() == (int)$collectionName);\r
+\r
+               // avoid directory traversal\r
+               // note that preg_replace() is requred to remove the last "/" or "\" if exists\r
+               $media = realpath($DIR_MEDIA);\r
+               $media = preg_replace('#[/\\\\]+$#','',$media);\r
+               $collectionDir = realpath( $DIR_MEDIA . $collectionName );\r
+               $collectionDir = preg_replace('#[/\\\\]+$#','',$collectionDir);\r
+               if (strpos($collectionDir,$media)!==0 || $collectionDir == $media) return false;\r
+\r
+               // private collections only accept uploads from their owners\r
+               // The "+1" of "strlen($media)+1" corresponds to "/" or "\".\r
+               $collectionName=substr($collectionDir,strlen($media)+1);\r
+               if (preg_match('/^[0-9]+$/',$collectionName))\r
+                       return ((int)$member->getID() == (int)$collectionName);\r
+\r
+               // other collections should exists and be writable\r
+               return (@is_dir($collectionDir) && @is_writable($collectionDir));\r
+       }\r
 
        /**
          * Adds an uploaded file to the media archive
 
        /**
          * Adds an uploaded file to the media archive