Ejemplo n.º 1
0
 function do_upload($page, $fname, $tmpname, $copyright = FALSE, $pass = NULL, $notouch = FALSE, $options = NULL)
 {
     // ページが無ければ空ページを作成(他のプラグインから呼ばれた時のため)
     if (!$this->func->is_page($page)) {
         $this->func->make_empty_page($page, false);
     }
     $overwrite = !empty($options['overwrite']);
     $changelog = isset($options['changelog']) ? $options['changelog'] : '';
     $add_mes = array();
     $has_json_msg = false;
     // ファイル名の正規化
     $fname = str_replace("", '', $fname);
     $fname = $this->func->basename(str_replace("\\", "/", $fname));
     $_action = 'insert';
     // style.css
     if ($fname === 'style.css' && $this->func->is_owner($page)) {
         if (is_file($tmpname)) {
             $_pagecss_file = $this->cont['CACHE_DIR'] . $this->func->get_pgid_by_name($page) . ".css";
             if (is_file($_pagecss_file)) {
                 unlink($_pagecss_file);
             }
             if (is_uploaded_file($tmpname) && move_uploaded_file($tmpname, $_pagecss_file) || @rename($tmpname, $_pagecss_file)) {
                 $this->attach_chmod($_pagecss_file);
                 // 空のファイルの場合はファイル削除
                 if (!trim(file_get_contents($_pagecss_file))) {
                     unlink($_pagecss_file);
                     return array('result' => TRUE, 'msg' => $this->root->_attach_messages['msg_unset_css'], 'has_json_msg' => TRUE);
                 } else {
                     $_data = file_get_contents($_pagecss_file);
                     // 管理者以外は外部ファイルの参照を禁止するなどの書き換え
                     if (!$this->root->userinfo['admin']) {
                         $_data = preg_replace('#(?:url\\s*\\(\\s*[\'"]?(?:(?:ht|f)tps?:)?//[^\\)]+?\\)|@import[^;\\r\\n]*?;|@import|(?:ht|f)tps?://)#i', '', $_data);
                     }
                     if (file_put_contents($_pagecss_file, $_data)) {
                         $add_mes[] = $this->root->_attach_messages['msg_set_css'];
                         $has_json_msg = true;
                     }
                     // 元ファイルを添付ファイルとして保存
                     if ($tmpname = tempnam($this->cont['CACHE_DIR'], 'atf')) {
                         file_put_contents($tmpname, $_data);
                         $overwrite = true;
                     }
                     clearstatcache();
                 }
             } else {
                 @unlink($tmpname);
                 return array('result' => FALSE, 'msg' => $this->root->_attach_messages['err_exists']);
             }
         }
     }
     // ページオーナー権限がない場合は拡張子をチェック
     $allow_extensions = $this->get_allow_extensions();
     if (empty($options['asSystem']) && !$overwrite && $allow_extensions && !$this->func->is_owner($page) && !preg_match("/\\.(" . join("|", $allow_extensions) . ")\$/i", $fname)) {
         return array('result' => FALSE, 'msg' => str_replace('$1', $this->func->htmlspecialchars(preg_replace('/.*\\.([^.]*)$/', "\$1", $fname)), $this->root->_attach_messages['err_extension']));
     }
     $_size = @getimagesize($tmpname);
     // イメージファイルの内容をチェック
     if ($_size) {
         $checkStr = $this->func->file_get_contents($tmpname, FALSE, NULL, 0, 10240);
         if (preg_match('/<(?:script|\\?php)/i', $checkStr)) {
             return array('result' => FALSE, 'msg' => 'It isn\'t a image file.');
         }
         // Flashファイルの検査
         if ($this->cont['ATTACH_UPLOAD_FLASH_ADMIN_ONLY']) {
             if (!$this->root->userinfo['admin'] && ($_size[2] === 4 || $_size[2] === 13)) {
                 return array('result' => FALSE, 'msg' => $this->root->_attach_messages['err_isflash']);
             }
         }
     }
     // オリジナルファイル名
     $org_fname = $fname;
     // 格納ファイル名指定あり
     if (!empty($this->root->vars['filename'])) {
         $fname = $this->root->vars['filename'];
     }
     // 格納ファイル名文字数チェック(SQL varchar(255) - strlen('_\d\d\d'))
     $fname = function_exists('mb_strcut') ? mb_strcut($fname, 0, 251) : substr($fname, 0, 251);
     // ファイル名 文字数のチェック
     $fname = $this->regularize_fname($fname, $page);
     if (!$overwrite) {
         // ファイル名が存在する場合は、数字を付け加える
         if (preg_match("/^(.+)(\\.[^.]*)\$/", $fname, $match)) {
             $_fname = $match[1];
             $_ext = $match[2];
         } else {
             $_fname = $fname;
             $_ext = '';
         }
         $fi = 0;
         do {
             $obj = new XpWikiAttachFile($this->xpwiki, $page, $fname);
             $fname = $_fname . '_' . $fi++ . $_ext;
         } while ($obj->exist);
     } else {
         $obj = new XpWikiAttachFile($this->xpwiki, $page, $fname);
         if (is_file($obj->filename)) {
             unlink($obj->filename);
             $_action = "update";
         }
     }
     if (is_uploaded_file($tmpname)) {
         if (move_uploaded_file($tmpname, $obj->filename)) {
             $this->attach_chmod($obj->filename);
         } else {
             return array('result' => FALSE, 'msg' => $this->root->_attach_messages['err_noexist']);
         }
     } else {
         if (!is_file($tmpname) || !filesize($tmpname)) {
             if (is_file($tmpname)) {
                 unlink($tmpname);
             }
             return array('result' => FALSE, 'msg' => $this->root->_attach_messages['err_noexist']);
         }
         if (rename($tmpname, $obj->filename)) {
             $this->attach_chmod($obj->filename);
         } else {
             unlink($tmpname);
             return array('result' => FALSE, 'msg' => $this->root->_attach_messages['err_noexist']);
         }
     }
     if ($this->func->is_page($page)) {
         if (!$notouch) {
             if (!$changelog) {
                 $changelog = 'Attached file: ' . $this->func->htmlspecialchars($obj->file);
             }
             $this->root->rtf['page_touch'][$page][] = $changelog;
         }
         $this->func->clear_page_cache($page);
     }
     if (!empty($options['asSystem'])) {
         $_uid = 0;
         $_ucd = 'SYSTEM';
         $_uname = 'System';
         $_admins = 0;
     } else {
         $_uid = $this->root->userinfo['uid'];
         $_ucd = $this->root->userinfo['ucd'];
         $_uname = $this->root->userinfo['uname'];
         $_admins = (int) $this->func->check_admin($this->root->userinfo['uid']);
     }
     if ($_size && version_compare(HypCommonFunc::get_version(), '20150515', '>=')) {
         // 自動回転を試みる
         HypCommonFunc::rotateImage($obj->filename, 0, 95, $_size);
         if (!empty($this->root->vars['rmgps'])) {
             HypCommonFunc::removeExifGps($obj->filename, $_size);
         }
     }
     $obj->getstatus();
     $obj->status['age'] = 0;
     $obj->status['pass'] = ($pass !== TRUE and $pass !== NULL) ? $pass : '';
     $obj->status['copyright'] = $copyright;
     $obj->status['owner'] = $_uid;
     $obj->status['ucd'] = $_ucd;
     $obj->status['uname'] = $_uname;
     $obj->status['md5'] = md5_file($obj->filename);
     $obj->status['admins'] = $_admins;
     $obj->status['org_fname'] = $org_fname;
     $obj->status['imagesize'] = $obj->getimagesize($obj->filename);
     $obj->status['mime'] = $this->attach_mime_content_type($obj->filename, $obj->status);
     $obj->action = $_action;
     $obj->putstatus();
     if (!empty($this->root->vars['refid'])) {
         $this->ref_replace($page, $this->root->vars['refid'], $obj->file, $obj->status['imagesize']);
     }
     return array('result' => TRUE, 'msg' => $add_mes ? join("\n", $add_mes) : $this->root->_attach_messages['msg_uploaded'], 'name' => $obj->file, 'has_json_msg' => $has_json_msg);
 }