/**
  *  modified image request with invalid token
  *  expect: 412 status code
  */
 function test_invalid_token()
 {
     $invalid_tokens = array('invalid_token_wrongid' => media_get_token('junk', 200, 100), 'invalid_token_wrongh' => media_get_token($this->media, 200, 10), 'invalid_token_wrongw' => media_get_token($this->media, 20, 100), 'invalid_token_wrongwh' => media_get_token($this->media, 20, 10));
     foreach ($invalid_tokens as $invalid_token) {
         $this->assertEquals(412, $this->fetchResponse('tok=' . $invalid_token . '&')->getStatusCode());
     }
 }
 /**
  *  native image request which doesn't require a token
  *  try: with a token & without a token
  *  expect: (for both) header with mime-type, content matching source image filesize & no error response
  */
 function test_no_token_required()
 {
     $this->width = $this->height = 0;
     // no width & height, means image request at native dimensions
     $any_token = 'tok=' . media_get_token('junk', 200, 100) . '&';
     $no_token = '';
     $bytes = filesize(mediaFN($this->media));
     foreach (array($any_token, $no_token) as $token) {
         $response = $this->fetchResponse($token);
         $this->assertTrue((bool) $response->getHeader('Content-Type'));
         $this->assertEquals(strlen($response->getContent()), $bytes);
         $status_code = $response->getStatusCode();
         $this->assertTrue(is_null($status_code) || 200 == $status_code);
     }
 }
Exemple #3
0
 function test_ml_imgresize_array_external()
 {
     global $conf;
     $conf['useslash'] = 0;
     $conf['userewrite'] = 0;
     $ids = array('https://example.com/lib/tpl/dokuwiki/images/logo.png', 'http://example.com/lib/tpl/dokuwiki/images/logo.png', 'ftp://example.com/lib/tpl/dokuwiki/images/logo.png');
     $w = 80;
     $args = array('w' => $w);
     foreach ($ids as $id) {
         $tok = media_get_token($id, $w, 0);
         $hash = substr(PassHash::hmac('md5', $id, auth_cookiesalt()), 0, 6);
         $expect = DOKU_BASE . $this->script . '?w=' . $w . '&tok=' . $tok . '&media=' . rawurlencode($id);
         $this->assertEquals($expect, ml($id, $args));
     }
     $h = 50;
     $args = array('h' => $h);
     $tok = media_get_token($id, $h, 0);
     $expect = DOKU_BASE . $this->script . '?h=' . $h . '&tok=' . $tok . '&media=' . rawurlencode($id);
     $this->assertEquals($expect, ml($id, $args));
     $w = 80;
     $h = 50;
     $args = array('w' => $w, 'h' => $h);
     $tok = media_get_token($id, $w, $h);
     $expect = DOKU_BASE . $this->script . '?w=' . $w . '&h=' . $h . '&tok=' . $tok . '&media=' . rawurlencode($id);
     $this->assertEquals($expect, ml($id, $args));
 }
Exemple #4
0
/**
 * Build a link to a media file
 *
 * Will return a link to the detail page if $direct is false
 *
 * The $more parameter should always be given as array, the function then
 * will strip default parameters to produce even cleaner URLs
 *
 * @param string  $id     the media file id or URL
 * @param mixed   $more   string or array with additional parameters
 * @param bool    $direct link to detail page if false
 * @param string  $sep    URL parameter separator
 * @param bool    $abs    Create an absolute URL
 * @return string
 */
function ml($id = '', $more = '', $direct = true, $sep = '&', $abs = false)
{
    global $conf;
    $isexternalimage = media_isexternal($id);
    if (!$isexternalimage) {
        $id = cleanID($id);
    }
    if (is_array($more)) {
        // add token for resized images
        if (!empty($more['w']) || !empty($more['h']) || $isexternalimage) {
            $more['tok'] = media_get_token($id, $more['w'], $more['h']);
        }
        // strip defaults for shorter URLs
        if (isset($more['cache']) && $more['cache'] == 'cache') {
            unset($more['cache']);
        }
        if (empty($more['w'])) {
            unset($more['w']);
        }
        if (empty($more['h'])) {
            unset($more['h']);
        }
        if (isset($more['id']) && $direct) {
            unset($more['id']);
        }
        if (isset($more['rev']) && !$more['rev']) {
            unset($more['rev']);
        }
        $more = buildURLparams($more, $sep);
    } else {
        $matches = array();
        if (preg_match_all('/\\b(w|h)=(\\d*)\\b/', $more, $matches, PREG_SET_ORDER) || $isexternalimage) {
            $resize = array('w' => 0, 'h' => 0);
            foreach ($matches as $match) {
                $resize[$match[1]] = $match[2];
            }
            $more .= $more === '' ? '' : $sep;
            $more .= 'tok=' . media_get_token($id, $resize['w'], $resize['h']);
        }
        $more = str_replace('cache=cache', '', $more);
        //skip default
        $more = str_replace(',,', ',', $more);
        $more = str_replace(',', $sep, $more);
    }
    if ($abs) {
        $xlink = DOKU_URL;
    } else {
        $xlink = DOKU_BASE;
    }
    // external URLs are always direct without rewriting
    if ($isexternalimage) {
        $xlink .= 'lib/exe/fetch.php';
        $xlink .= '?' . $more;
        $xlink .= $sep . 'media=' . rawurlencode($id);
        return $xlink;
    }
    $id = idfilter($id);
    // decide on scriptname
    if ($direct) {
        if ($conf['userewrite'] == 1) {
            $script = '_media';
        } else {
            $script = 'lib/exe/fetch.php';
        }
    } else {
        if ($conf['userewrite'] == 1) {
            $script = '_detail';
        } else {
            $script = 'lib/exe/detail.php';
        }
    }
    // build URL based on rewrite mode
    if ($conf['userewrite']) {
        $xlink .= $script . '/' . $id;
        if ($more) {
            $xlink .= '?' . $more;
        }
    } else {
        if ($more) {
            $xlink .= $script . '?' . $more;
            $xlink .= $sep . 'media=' . $id;
        } else {
            $xlink .= $script . '?media=' . $id;
        }
    }
    return $xlink;
}
/**
 * Check for media for preconditions and return correct status code
 *
 * READ: MEDIA, MIME, EXT, CACHE
 * WRITE: MEDIA, FILE, array( STATUS, STATUSMESSAGE )
 *
 * @author Gerry Weissbach <*****@*****.**>
 *
 * @param string $media  reference to the media id
 * @param string $file   reference to the file variable
 * @param string $rev
 * @param int    $width
 * @param int    $height
 * @return array as array(STATUS, STATUSMESSAGE)
 */
function checkFileStatus(&$media, &$file, $rev = '', $width = 0, $height = 0)
{
    global $MIME, $EXT, $CACHE, $INPUT;
    //media to local file
    if (media_isexternal($media)) {
        //check token for external image and additional for resized and cached images
        if (media_get_token($media, $width, $height) !== $INPUT->str('tok')) {
            return array(412, 'Precondition Failed');
        }
        //handle external images
        if (strncmp($MIME, 'image/', 6) == 0) {
            $file = media_get_from_URL($media, $EXT, $CACHE);
        }
        if (!$file) {
            //download failed - redirect to original URL
            return array(302, $media);
        }
    } else {
        $media = cleanID($media);
        if (empty($media)) {
            return array(400, 'Bad request');
        }
        // check token for resized images
        if (($width || $height) && media_get_token($media, $width, $height) !== $INPUT->str('tok')) {
            return array(412, 'Precondition Failed');
        }
        //check permissions (namespace only)
        if (auth_quickaclcheck(getNS($media) . ':X') < AUTH_READ) {
            return array(403, 'Forbidden');
        }
        $file = mediaFN($media, $rev);
    }
    //check file existance
    if (!file_exists($file)) {
        return array(404, 'Not Found');
    }
    return array(200, null);
}
Exemple #6
0
 /**
  * Renders internal and external media with exif info at bottom of each JPEG image
  *
  * @author Andreas Gohr <*****@*****.**>
  * @param string $src       media ID
  * @param string $title     descriptive text
  * @param string $align     left|center|right
  * @param int    $width     width of media in pixel
  * @param int    $height    height of media in pixel
  * @param string $cache     cache|recache|nocache
  * @param bool   $render    should the media be embedded inline or just linked
  * @return string
  */
 function _media($src, $title = null, $align = null, $width = null, $height = null, $cache = null, $render = true)
 {
     $ret = '';
     list($ext, $mime) = mimetype($src);
     if (substr($mime, 0, 5) == 'image') {
         // first get the $title
         if (!is_null($title)) {
             $title = $this->_xmlEntities($title);
         } elseif ($ext == 'jpg' || $ext == 'jpeg') {
             //try to use the caption from IPTC/EXIF
             require_once DOKU_INC . 'lib/plugins/colorbox/JpegMetaGPS.php';
             $jpeg = new JpegMetaGPS(mediaFN($src));
             if ($jpeg !== false) {
                 $cap = $jpeg->getTitle();
             }
             if (!empty($cap)) {
                 $title = $this->_xmlEntities($cap);
             }
         }
         if (!$render) {
             // if the picture is not supposed to be rendered
             // return the title of the picture
             if (!$title) {
                 // just show the sourcename
                 $title = $this->_xmlEntities(utf8_basename(noNS($src)));
             }
             return $title;
         }
         //add image tag
         if (($ext == 'jpg' || $ext == 'jpeg') && !$width && !strpos($src, 'wiki:dokuwiki')) {
             // force to scale image to 680px
             $ret .= '<img src="' . ml($src, array('w' => "680", 'h' => $height, 'cache' => $cache, 'rev' => $this->_getLastMediaRevisionAt($src))) . '"';
         } else {
             $ret .= '<img src="' . ml($src, array('w' => $width, 'h' => $height, 'cache' => $cache, 'rev' => $this->_getLastMediaRevisionAt($src))) . '"';
         }
         $ret .= ' class="media' . $align . '"';
         if ($title) {
             $ret .= ' title="' . $title . '"';
             $ret .= ' alt="' . $title . '"';
         } else {
             $ret .= ' alt=""';
         }
         if (!is_null($width)) {
             $ret .= ' width="' . $this->_xmlEntities($width) . '"';
         }
         if (!is_null($height)) {
             $ret .= ' height="' . $this->_xmlEntities($height) . '"';
         }
         // add exif and gps info at the bottom of each image
         if ($ext == 'jpg' || $ext == 'jpeg') {
             //try to use the caption from IPTC/EXIF
             if (!$jepg) {
                 require_once DOKU_INC . 'lib/plugins/colorbox/JpegMetaGPS.php';
                 $jpeg = new JpegMetaGPS(mediaFN($src));
             }
             if ($jpeg !== false) {
                 $infoshort = $jpeg->getShortExifInfo();
                 $info = $jpeg->getExifInfo();
                 $gpslink = $jpeg->getGPSInfo();
                 $ret .= ' exif="' . implode(';', array_map(function ($v, $k) {
                     if ($v) {
                         return strtolower($k) . ':' . $v . '';
                     }
                 }, $infoshort, array_keys($infoshort))) . '"';
                 if ($gpslink) {
                     $ret .= ' map="' . $gpslink . '"';
                 }
                 $ret .= ' token="' . media_get_token($src, "1360", $height) . '"';
                 $ret .= '/></a>';
                 $ret .= '<div class="exiftitle">' . $title . '</div>';
                 $ret .= '<div class="exif">';
                 $ret .= implode(', ', array_map(function ($v, $k) {
                     return $k . '=' . $v;
                 }, $info, array_keys($info)));
                 if ($gpslink) {
                     $ret .= ' <a href=' . $gpslink . '>Google GPS Location';
                 }
                 $ret .= ' </a></div>';
                 $ret .= '<a>';
             }
         }
         //
     } elseif (media_supportedav($mime, 'video') || media_supportedav($mime, 'audio')) {
         // first get the $title
         $title = !is_null($title) ? $this->_xmlEntities($title) : false;
         if (!$render) {
             // if the file is not supposed to be rendered
             // return the title of the file (just the sourcename if there is no title)
             return $title ? $title : $this->_xmlEntities(utf8_basename(noNS($src)));
         }
         $att = array();
         $att['class'] = "media{$align}";
         if ($title) {
             $att['title'] = $title;
         }
         if (media_supportedav($mime, 'video')) {
             //add video
             $ret .= $this->_video($src, $width, $height, $att);
         }
         if (media_supportedav($mime, 'audio')) {
             //add audio
             $ret .= $this->_audio($src, $att);
         }
     } elseif ($mime == 'application/x-shockwave-flash') {
         if (!$render) {
             // if the flash is not supposed to be rendered
             // return the title of the flash
             if (!$title) {
                 // just show the sourcename
                 $title = utf8_basename(noNS($src));
             }
             return $this->_xmlEntities($title);
         }
         $att = array();
         $att['class'] = "media{$align}";
         if ($align == 'right') {
             $att['align'] = 'right';
         }
         if ($align == 'left') {
             $att['align'] = 'left';
         }
         $ret .= html_flashobject(ml($src, array('cache' => $cache), true, '&'), $width, $height, array('quality' => 'high'), null, $att, $this->_xmlEntities($title));
     } elseif ($title) {
         // well at least we have a title to display
         $ret .= $this->_xmlEntities($title);
     } else {
         // just show the sourcename
         $ret .= $this->_xmlEntities(utf8_basename(noNS($src)));
     }
     return $ret;
 }
Exemple #7
0
 /**
  * Defines how a thumbnail should look like
  */
 function _image(&$img, $data)
 {
     global $ID;
     global $conf;
     // calculate thumbnail size
     if (!$data['crop']) {
         $w = (int) $this->_meta($img, 'width');
         $h = (int) $this->_meta($img, 'height');
         if ($conf['syslog']) {
             syslog(LOG_WARNING, '[gallery:syntax.php] image file: ' . $conf['mediadir'] . utf8_encodeFN(str_replace(':', '/', $img['id'])) . $img['file'] . '. size: ' . $w . 'x' . $h);
         }
         if ($w && $h) {
             $dim = array();
             if ($w > $data['tw'] || $h > $data['th']) {
                 $fr = $w / $h;
                 if ($fr >= $data['tw'] / $data['th']) {
                     $w = $data['tw'];
                     $h = round($w / $fr);
                 } else {
                     $h = $data['th'];
                     $w = round($h * $fr);
                 }
                 $dim = array('w' => $w, 'h' => $h);
                 if ($conf['syslog']) {
                     syslog(LOG_WARNING, '[gallery:syntax.php] image file: ' . $conf['mediadir'] . utf8_encodeFN(str_replace(':', '/', $img['id'])) . $img['file'] . '. reize to: ' . $w . 'x' . $h);
                 }
             }
         } else {
             // this should not happen but if it does this usually means a corrupted image file therefore we want to log it
             syslog(LOG_WARNING, 'no size info found which is likely due to corrupted image file. force crop to ' . $data['tw'] . 'x' . $data['th'] . '. file: ' . $conf['mediadir'] . utf8_encodeFN(str_replace(':', '/', $img['id'])) . $img['file']);
             $data['crop'] = true;
             // no size info -> always crop
         }
     }
     if ($data['crop']) {
         $w = $data['tw'];
         $h = $data['th'];
         $dim = array('w' => $w, 'h' => $h);
     }
     //prepare img attributes
     $i = array();
     $i['width'] = $w;
     $i['height'] = $h;
     $i['border'] = 0;
     if ($this->_meta($img, 'title')) {
         $i['alt'] = $this->_meta($img, 'title');
     } else {
         $i['alt'] = end(explode(":", $img['id']));
     }
     $i['longdesc'] = str_replace("\n", ' ', $this->_meta($img, 'desc'));
     if (!$i['longdesc']) {
         unset($i['longdesc']);
     }
     $i['class'] = 'tn';
     // get exif and gps info
     $orientation = $img['meta']->getField("Orientation");
     if ($conf['syslog']) {
         syslog(LOG_WARNING, '[gallery:syntax.php] orientation: ' . $orientation);
     }
     switch ($orientation) {
         case 6:
             if ($i['width'] > $i['height']) {
                 // swap width and height if the image is going to be rotated vertically
                 if ($conf['syslog']) {
                     syslog(LOG_WARNING, 'swap width and height as the image is going to be rotated vertically');
                 }
                 $old_width = $i['width'];
                 $i['width'] = $i['height'];
                 $i['height'] = $old_width;
             }
             break;
         case 8:
             if ($i['width'] > $i['height']) {
                 // swap width and height if the image is going to be rotated vertically
                 if ($conf['syslog']) {
                     syslog(LOG_WARNING, 'swap width and height as the image is going to be rotated vertically');
                 }
                 $old_width = $i['width'];
                 $i['width'] = $i['height'];
                 $i['height'] = $old_width;
             }
             break;
     }
     require_once DOKU_INC . 'lib/plugins/colorbox/JpegMetaGPS.php';
     $jpeg = new JpegMetaGPS(mediaFN($img['id']));
     if ($jpeg !== false) {
         $info = $jpeg->getShortExifInfo();
         $gpslink = $jpeg->getGPSInfo();
         if ($info) {
             $i['exif'] = implode(';', array_map(function ($v, $k) {
                 if ($v) {
                     return strtolower($k) . ':' . $v . '';
                 }
             }, $info, array_keys($info)));
         }
         if ($gpslink) {
             $i['map'] = $gpslink;
         }
         $i['token'] = media_get_token($img['id'], "1360", "0");
     }
     $iatt = buildAttributes($i);
     $src = ml($img['id'], $dim);
     // prepare lightbox dimensions
     $w_lightbox = (int) $this->_meta($img, 'width');
     $h_lightbox = (int) $this->_meta($img, 'height');
     $dim_lightbox = array();
     if ($w_lightbox > $data['iw'] || $h_lightbox > $data['ih']) {
         $ratio = $this->_ratio($img, $data['iw'], $data['ih']);
         $w_lightbox = floor($w_lightbox * $ratio);
         $h_lightbox = floor($h_lightbox * $ratio);
         $dim_lightbox = array('w' => $w_lightbox, 'h' => $h_lightbox);
     }
     //prepare link attributes
     $a = array();
     $a['title'] = $this->_meta($img, 'title');
     if ($data['lightbox']) {
         $href = ml($img['id'], $dim_lightbox);
         $a['class'] = "lightbox JSnocheck";
         $a['rel'] = 'lightbox[gal-' . substr(md5($ID), 4) . ']';
         //unique ID for the gallery
     } elseif ($img['detail'] && !$data['direct']) {
         $href = $img['detail'];
     } else {
         $href = ml($img['id'], array('id' => $ID), $data['direct']);
     }
     $aatt = buildAttributes($a);
     // prepare output
     $ret = '';
     $ret .= '<a href="' . $href . '" ' . $aatt . '>';
     $ret .= '<img src="' . $src . '" ' . $iatt . ' />';
     $ret .= '</a>';
     return $ret;
 }
 /**
  * Defines how a thumbnail should look like
  */
 function _image($data, &$renderer = null, $mode = 'xhtml')
 {
     global $ID;
     if (is_null($renderer) || empty($data['src'])) {
         return false;
     }
     if (!is_array($data['params'])) {
         $data['params'] = array();
     }
     //prepare link attributes
     // can use reflected images
     $reflect = array();
     if ($reflection = plugin_load('syntax', 'reflect')) {
         $reflect = array('reflect' => $this->getConf('reflect') ? 1 : 0, 'bgc' => $this->getConf('reflectBackground'));
     }
     // Start Section
     if ($mode != 'metadata') {
         $renderer->doc .= '<div class="imageflow_image">' . NL;
     }
     // Display
     $data['params']['tok'] = media_get_token($data['src'], $data['params']['w'], $data['params']['h']);
     $href = ml($data['src'], array_merge($data['params'], $reflect), true, '&');
     if ($mode != 'metadata' && empty($data['alternate_desc'])) {
         $renderer->doc .= '<img src="' . $href . '" alt="" class="imageflow__noscript__image media"/>';
     }
     // Set Data
     $fn = mediaFN($data['src']);
     $data['src'] = ml($data['src']);
     $data['params'] = array_merge($data['params'], $reflect);
     // Remove everything except the params.
     $data['desc'] = trim($data['desc']);
     $data['title'] = trim($data['title']);
     if (empty($data['desc']) && ($meta = new JpegMeta($fn))) {
         $data['title'] = $meta->getField('Iptc.Headline');
         $data['desc'] = $meta->getField('Iptc.Caption');
     }
     if ($mode != 'metadata') {
         if (!empty($data['alternate_desc'])) {
             $renderer->doc .= $data['alternate_desc'];
         } else {
             $renderer->doc .= '<div class="imageflow_caption">' . NL;
             if (!empty($data['title'])) {
                 $renderer->doc .= "<h3 class=\"imageflow__title\">{$data['title']}</h3>" . NL;
             }
             if (!empty($data['desc'])) {
                 $renderer->doc .= "<p class=\"imageflow__text\">{$data['desc']}</p>" . NL;
             }
             // End Caption
             $renderer->doc .= '</div>' . NL;
         }
         // End Section
         $renderer->doc .= '<div class="clearer"></div>' . NL . '</div>' . NL;
     } else {
         // Add Metadata
         unset($data['alternate_desc']);
         if (!$data['isImage'] && !empty($data['linkto'])) {
             $data['id'] = $data['linkto'];
             unset($data['linkto']);
         }
         $renderer->meta['relation']['imageflow'][$this->sectionID[sizeof($this->sectionID) - 1]][] = $data;
     }
     return $data;
 }