Example #1
0
/**
 * Inline Images
 *
 * Syntax: [image.png size=50% border=n align= hspace= vspace= width= height=]
 * Disallows sizes which are too small.
 * Spammers may use such (typically invisible) image attributes to raise their GoogleRank.
 *
 * Handle embeddable objects, like svg, class, vrml, swf, svgz, pdf, avi, wmv especially.
 */
function LinkImage($url, $alt = "")
{
    $force_img = "png|jpg|gif|jpeg|bmp|pl|cgi";
    // Disallow tags in img src urls. Typical CSS attacks.
    // FIXME: Is this needed (or sufficient?)
    // FIXED: This was broken for moniker:TP30 test/image.png => url="moniker:TP30" attr="test/image.png"
    $ori_url = $url;
    // support new syntax: [prefix/image.jpg size=50% border=n]
    if (empty($alt)) {
        $alt = "";
    }
    // Extract URL
    $arr = explode(' ', $url);
    if (!empty($arr)) {
        $url = $arr[0];
    }
    if (!IsSafeURL($url)) {
        $link = HTML::span(array('class' => 'error'), _("BAD URL -- remove all of <, >, \""));
        return $link;
    }
    // spaces in inline images must be %20 encoded!
    $link = HTML::img(array('src' => $url));
    // Extract attributes
    $arr = parse_attributes(strstr($ori_url, " "));
    foreach ($arr as $attr => $value) {
        // These attributes take strings: lang, id, title, alt
        if ($attr == "lang" || $attr == "id" || $attr == "title" || $attr == "alt") {
            $link->setAttr($attr, $value);
        } elseif ($attr == "align" && ($value == "bottom" || $value == "middle" || $value == "top" || $value == "left" || $value == "right")) {
            $link->setAttr($attr, $value);
        } elseif (($attr == "border" || $attr == "hspace" || $attr == "vspace") && is_numeric($value)) {
            $link->setAttr($attr, (int) $value);
        } elseif (($attr == "height" || $attr == "width") && preg_match('/\\d+[%p]?x?/', $value)) {
            $link->setAttr($attr, $value);
        } elseif ($attr == "size") {
            if (preg_match('/(\\d+%)/', $value, $m)) {
                $link->setAttr('width', $m[1]);
                $link->setAttr('height', $m[1]);
            } elseif (preg_match('/(\\d+)x(\\d+)/', $value, $m)) {
                $link->setAttr('width', $m[1]);
                $link->setAttr('height', $m[2]);
            }
        } else {
            $link = HTML::span(array('class' => 'error'), sprintf(_("Invalid image attribute \"%s\" %s=%s"), $url, $attr, $value));
            return $link;
        }
    }
    // Correct silently the most common error
    if ($url != $ori_url and empty($arr) and !preg_match("/^http/", $url)) {
        // space belongs to the path
        $file = NormalizeLocalFileName($ori_url);
        if (file_exists($file)) {
            $link = HTML::img(array('src' => $ori_url));
            trigger_error(sprintf(_("Invalid image link fixed %s => %s. Spaces must be quoted with %%20."), $url, $ori_url), E_USER_WARNING);
        } elseif (string_starts_with($ori_url, getUploadDataPath())) {
            $file = substr($file, strlen(getUploadDataPath()));
            $path = getUploadFilePath() . $file;
            if (file_exists($path)) {
                trigger_error(sprintf(_("Invalid image link fixed \"%s\" => \"%s\".\n Spaces must be quoted with %%20."), $url, $ori_url), E_USER_WARNING);
                $link->setAttr('src', getUploadDataPath() . $file);
                $url = $ori_url;
            }
        }
    }
    if (!$link->getAttr('alt')) {
        $link->setAttr('alt', $alt);
    }
    // Check width and height as spam countermeasure
    if ($width = $link->getAttr('width') and $height = $link->getAttr('height')) {
        //$width  = (int) $width; // px or % or other suffix
        //$height = (int) $height;
        if ($width < 3 and $height < 10 or $height < 3 and $width < 20 or $height < 7 and $width < 7) {
            $link = HTML::span(array('class' => 'error'), _("Invalid image size"));
            return $link;
        }
    } else {
        $size = 0;
        // Prepare for getimagesize($url)
        // $url only valid for external urls, otherwise local path
        if (DISABLE_GETIMAGESIZE) {
        } elseif (!preg_match("/\\.{$force_img}\$/i", $url)) {
        } elseif (preg_match("/^http/", $url)) {
            // external url
            $size = @getimagesize($url);
        } else {
            // local file
            if (file_exists($file = NormalizeLocalFileName($url))) {
                // here
                $size = @getimagesize($file);
            } elseif (file_exists(NormalizeLocalFileName(urldecode($url)))) {
                $size = @getimagesize($file);
                $link->setAttr('src', rawurldecode($url));
            } elseif (string_starts_with($url, getUploadDataPath())) {
                // there
                $file = substr($file, strlen(getUploadDataPath()));
                $path = getUploadFilePath() . rawurldecode($file);
                $size = @getimagesize($path);
                $link->setAttr('src', getUploadDataPath() . rawurldecode($file));
            } else {
                // elsewhere
                global $request;
                $size = @getimagesize($request->get('DOCUMENT_ROOT') . urldecode($url));
            }
        }
        if ($size) {
            $width = $size[0];
            $height = $size[1];
            if ($width < 3 and $height < 10 or $height < 3 and $width < 20 or $height < 7 and $width < 7) {
                $link = HTML::span(array('class' => 'error'), _("Invalid image size"));
                return $link;
            }
        }
    }
    $link->setAttr('class', 'inlineimage');
    /* Check for inlined objects. Everything allowed in INLINE_IMAGES besides
     * png|jpg|gif|jpeg|bmp|pl|cgi.  If no image it is an object to embed.
     * Note: Allow cgi's (pl,cgi) returning images.
     */
    if (!preg_match("/\\.(" . $force_img . ")/i", $url)) {
        // HTML::img(array('src' => $url, 'alt' => $alt, 'title' => $alt));
        // => HTML::object(array('src' => $url)) ...;
        return ImgObject($link, $ori_url);
    }
    return $link;
}
Example #2
0
/**
 * Inline Images
 *
 * Syntax: [image.png size=50% border=n align= hspace= vspace= width= height=]
 * Disallows sizes which are too small. 
 * Spammers may use such (typically invisible) image attributes to higher their GoogleRank.
 *
 * Handle embeddable objects, like svg, class, vrml, swf, svgz, pdf, avi, wmv especially.
 */
function LinkImage($url, $alt = false)
{
    $force_img = "png|jpg|gif|jpeg|bmp|pl|cgi";
    // Disallow tags in img src urls. Typical CSS attacks.
    // FIXME: Is this needed (or sufficient?)
    if (!IsSafeURL($url)) {
        $link = HTML::strong(HTML::u(array('class' => 'baduri'), _("BAD URL -- remove all of <, >, \"")));
    } else {
        // support new syntax: [image.jpg size=50% border=n]
        if (!preg_match("/\\.(" . $force_img . ")/i", $url)) {
            $ori_url = $url;
        }
        $arr = split(' ', $url);
        if (count($arr) > 1) {
            $url = $arr[0];
        }
        if (empty($alt)) {
            $alt = basename($url);
        }
        $link = HTML::img(array('src' => $url, 'alt' => $alt, 'title' => $alt));
        if (count($arr) > 1) {
            array_shift($arr);
            foreach ($arr as $attr) {
                if (preg_match('/^size=(\\d+%)$/', $attr, $m)) {
                    $link->setAttr('width', $m[1]);
                    $link->setAttr('height', $m[1]);
                }
                if (preg_match('/^size=(\\d+)x(\\d+)$/', $attr, $m)) {
                    $link->setAttr('width', $m[1]);
                    $link->setAttr('height', $m[2]);
                }
                if (preg_match('/^border=(\\d+)$/', $attr, $m)) {
                    $link->setAttr('border', $m[1]);
                }
                if (preg_match('/^align=(\\w+)$/', $attr, $m)) {
                    $link->setAttr('align', $m[1]);
                }
                if (preg_match('/^hspace=(\\d+)$/', $attr, $m)) {
                    $link->setAttr('hspace', $m[1]);
                }
                if (preg_match('/^vspace=(\\d+)$/', $attr, $m)) {
                    $link->setAttr('vspace', $m[1]);
                }
            }
        }
        // Check width and height as spam countermeasure
        if ($width = $link->getAttr('width') and $height = $link->getAttr('height')) {
            //$width  = (int) $width; // px or % or other suffix
            //$height = (int) $height;
            if ($width < 3 and $height < 10 or $height < 3 and $width < 20 or $height < 7 and $width < 7) {
                trigger_error(_("Invalid image size"), E_USER_WARNING);
                return '';
            }
        } else {
            // Older php versions crash here with certain png's:
            // confirmed for 4.1.2, 4.1.3, 4.2.3; 4.3.2 and 4.3.7 are ok
            //   http://phpwiki.sourceforge.net/demo/themes/default/images/http.png
            // See http://bugs.php.net/search.php?cmd=display&search_for=getimagesize
            if (!check_php_version(4, 3) and preg_match("/^http.+\\.png\$/i", $url)) {
            } elseif (!DISABLE_GETIMAGESIZE and $size = @getimagesize($url)) {
                $width = $size[0];
                $height = $size[1];
                if ($width < 3 and $height < 10 or $height < 3 and $width < 20 or $height < 7 and $width < 7) {
                    trigger_error(_("Invalid image size"), E_USER_WARNING);
                    return '';
                }
            }
        }
    }
    $link->setAttr('class', 'inlineimage');
    /* Check for inlined objects. Everything allowed in INLINE_IMAGES besides
     * png|jpg|gif|jpeg|bmp|pl|cgi
     * Note: Allow cgi's (pl,cgi) returning images.
     */
    if (!preg_match("/\\.(" . $force_img . ")/i", $url)) {
        //HTML::img(array('src' => $url, 'alt' => $alt, 'title' => $alt));
        // => HTML::object(array('src' => $url)) ...;
        return ImgObject($link, $ori_url);
    }
    return $link;
}