summaryrefslogtreecommitdiff
path: root/inc/media.php
diff options
context:
space:
mode:
authorKlap-in <klapinklapin@gmail.com>2013-07-14 13:35:06 +0200
committerKlap-in <klapinklapin@gmail.com>2013-07-14 13:35:06 +0200
commit33c3b3817b00aa9384760813643fac0e33daaaff (patch)
tree481c880b00a32ba5887834b52a17248bac8bfc7c /inc/media.php
parent040f0e135c37c5b544f16277ff69205369df5f1f (diff)
parentfbd8067eeeb9f424981aad8b283e17f734c738c3 (diff)
downloadrpg-33c3b3817b00aa9384760813643fac0e33daaaff.tar.gz
rpg-33c3b3817b00aa9384760813643fac0e33daaaff.tar.bz2
merge master in branch
Diffstat (limited to 'inc/media.php')
-rw-r--r--inc/media.php104
1 files changed, 92 insertions, 12 deletions
diff --git a/inc/media.php b/inc/media.php
index 572b1177c..fbe1363ec 100644
--- a/inc/media.php
+++ b/inc/media.php
@@ -83,6 +83,32 @@ function media_metasave($id,$auth,$data){
}
/**
+ * check if a media is external source
+ *
+ * @author Gerrit Uitslag <klapinklapin@gmail.com>
+ * @param string $id the media ID or URL
+ * @return bool
+ */
+function media_isexternal($id){
+ if (preg_match('#^(https?|ftp)://#i', $id)) return true;
+ return false;
+}
+
+/**
+ * Check if a media item is public (eg, external URL or readable by @ALL)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $id the media ID or URL
+ * @return bool
+ */
+function media_ispublic($id){
+ if(media_isexternal($id)) return true;
+ $id = cleanID($id);
+ if(auth_aclcheck(getNS($id).':*', '', array()) >= AUTH_READ) return true;
+ return false;
+}
+
+/**
* Display the form to edit image meta data
*
* @author Andreas Gohr <andi@splitbrain.org>
@@ -237,8 +263,7 @@ function media_upload_xhr($ns,$auth){
$realSize = stream_copy_to_stream($input, $target);
fclose($target);
fclose($input);
- if ($realSize != (int)$_SERVER["CONTENT_LENGTH"]){
- unlink($target);
+ if (isset($_SERVER["CONTENT_LENGTH"]) && ($realSize != (int)$_SERVER["CONTENT_LENGTH"])){
unlink($path);
return false;
}
@@ -1687,18 +1712,36 @@ function media_nstree($ns){
$ns = cleanID($ns);
if(empty($ns)){
global $ID;
- $ns = dirname(str_replace(':','/',$ID));
- if($ns == '.') $ns ='';
+ $ns = (string)getNS($ID);
}
- $ns = utf8_encodeFN(str_replace(':','/',$ns));
+
+ $ns_dir = utf8_encodeFN(str_replace(':','/',$ns));
$data = array();
- search($data,$conf['mediadir'],'search_index',array('ns' => $ns, 'nofiles' => true));
+ search($data,$conf['mediadir'],'search_index',array('ns' => $ns_dir, 'nofiles' => true));
// wrap a list with the root level around the other namespaces
array_unshift($data, array('level' => 0, 'id' => '', 'open' =>'true',
'label' => '['.$lang['mediaroot'].']'));
+ // insert the current ns into the hierarchy if it isn't already part of it
+ $ns_parts = explode(':', $ns);
+ $tmp_ns = '';
+ $pos = 0;
+ foreach ($ns_parts as $level => $part) {
+ if ($tmp_ns) $tmp_ns .= ':'.$part;
+ else $tmp_ns = $part;
+
+ // find the namespace parts or insert them
+ while ($data[$pos]['id'] != $tmp_ns) {
+ if ($pos >= count($data) || ($data[$pos]['level'] <= $level+1 && strnatcmp(utf8_encodeFN($data[$pos]['id']), utf8_encodeFN($tmp_ns)) > 0)) {
+ array_splice($data, $pos, 0, array(array('level' => $level+1, 'id' => $tmp_ns, 'open' => 'true')));
+ break;
+ }
+ ++$pos;
+ }
+ }
+
echo html_buildlist($data,'idx','media_nstree_item','media_nstree_li');
}
@@ -1764,6 +1807,9 @@ function media_resize_image($file, $ext, $w, $h=0){
// we wont scale up to infinity
if($w > 2000 || $h > 2000) return $file;
+ // resize necessary? - (w,h) = native dimensions
+ if(($w == $info[0]) && ($h == $info[1])) return $file;
+
//cache
$local = getCacheName($file,'.media.'.$w.'x'.$h.'.'.$ext);
$mtime = @filemtime($local); // 0 if not exists
@@ -1797,26 +1843,33 @@ function media_crop_image($file, $ext, $w, $h=0){
// calculate crop size
$fr = $info[0]/$info[1];
$tr = $w/$h;
+
+ // check if the crop can be handled completely by resize,
+ // i.e. the specified width & height match the aspect ratio of the source image
+ if ($w == round($h*$fr)) {
+ return media_resize_image($file, $ext, $w);
+ }
+
if($tr >= 1){
if($tr > $fr){
$cw = $info[0];
- $ch = (int) $info[0]/$tr;
+ $ch = (int) ($info[0]/$tr);
}else{
- $cw = (int) $info[1]*$tr;
+ $cw = (int) ($info[1]*$tr);
$ch = $info[1];
}
}else{
if($tr < $fr){
- $cw = (int) $info[1]*$tr;
+ $cw = (int) ($info[1]*$tr);
$ch = $info[1];
}else{
$cw = $info[0];
- $ch = (int) $info[0]/$tr;
+ $ch = (int) ($info[0]/$tr);
}
}
// calculate crop offset
- $cx = (int) ($info[0]-$cw)/2;
- $cy = (int) ($info[1]-$ch)/3;
+ $cx = (int) (($info[0]-$cw)/2);
+ $cy = (int) (($info[1]-$ch)/3);
//cache
$local = getCacheName($file,'.media.'.$cw.'x'.$ch.'.crop.'.$ext);
@@ -1834,6 +1887,31 @@ function media_crop_image($file, $ext, $w, $h=0){
}
/**
+ * Calculate a token to be used to verify fetch requests for resized or
+ * cropped images have been internally generated - and prevent external
+ * DDOS attacks via fetch
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ *
+ * @param string $id id of the image
+ * @param int $w resize/crop width
+ * @param int $h resize/crop height
+ * @return string
+ */
+function media_get_token($id,$w,$h){
+ // token is only required for modified images
+ if ($w || $h) {
+ $token = $id;
+ if ($w) $token .= '.'.$w;
+ if ($h) $token .= '.'.$h;
+
+ return substr(PassHash::hmac('md5', $token, auth_cookiesalt()),0,6);
+ }
+
+ return '';
+}
+
+/**
* Download a remote file and return local filename
*
* returns false if download fails. Uses cached file if available and
@@ -1878,6 +1956,8 @@ function media_get_from_URL($url,$ext,$cache){
function media_image_download($url,$file){
global $conf;
$http = new DokuHTTPClient();
+ $http->keep_alive = false; // we do single ops here, no need for keep-alive
+
$http->max_bodysize = $conf['fetchsize'];
$http->timeout = 25; //max. 25 sec
$http->header_regexp = '!\r\nContent-Type: image/(jpe?g|gif|png)!i';