Skip to content

Instantly share code, notes, and snippets.

@akotulu
Last active November 14, 2022 21:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akotulu/ad4ea148031a266e51fb32f0a9b71718 to your computer and use it in GitHub Desktop.
Save akotulu/ad4ea148031a266e51fb32f0a9b71718 to your computer and use it in GitHub Desktop.
TinyMCE's tinybrowser plugin Flash replacement
<?php
// Removed deprecated functions
// sql_regcase
/* Create Folder */
function createfolder($dir, $perm)
{
// prevent hidden folder creation
$dir = ltrim($dir, '.');
// recursion with dirname function, returns parent directory by default (misleading name)
is_dir(dirname($dir)) || createfolder(dirname($dir), $perm);
// mkdir seems to be bugged by giving insufficient permissions (0777 results in drwxr-xr-x)
// Ubuntu 20.04.1 LTS, PHP 7.1.33-17
return mkdir($dir) && chmod($dir, octdec($perm));
}
/* Validate File Extensions */
function validateExtension($extension, $types)
{
if (in_array($extension, $types)) return false; else return true;
}
/* Display Alert Notifications */
function alert(&$notify)
{
$alert_num = count($notify['type']);
for ($i = 0; $i < $alert_num; $i++) {
$notify['message'][$i] = str_ireplace($_SERVER['DOCUMENT_ROOT'], '', $notify['message'][$i]);
?>
<div
class="alert<?php echo filter_str($notify['type'][$i]); ?>"><?php echo filter_str($notify['message'][$i]); ?></div>
<br/><?php
}
}
/* Sort File Array By Selected Order */
function sortfileorder(&$sortbynow, &$sortorder, &$file)
{
switch ($sortbynow) {
case 'name':
array_multisort($file['sortname'], $sortorder, $file['name'], $sortorder, $file['type'], $sortorder, $file['modified'], $sortorder, $file['size'], $sortorder, $file['dimensions'], $sortorder, $file['width'], $sortorder, $file['height'], $sortorder);
break;
case 'size':
array_multisort($file['size'], $sortorder, $file['sortname'], SORT_ASC, $file['name'], SORT_ASC, $file['type'], $sortorder, $file['modified'], $sortorder, $file['dimensions'], $sortorder, $file['width'], $sortorder, $file['height'], $sortorder);
break;
case 'type':
array_multisort($file['type'], $sortorder, $file['sortname'], SORT_ASC, $file['name'], SORT_ASC, $file['size'], $sortorder, $file['modified'], $sortorder, $file['dimensions'], $sortorder, $file['width'], $sortorder, $file['height'], $sortorder);
break;
case 'modified':
array_multisort($file['modified'], $sortorder, $file['name'], $sortorder, $file['name'], $sortorder, $file['type'], $sortorder, $file['size'], $sortorder, $file['dimensions'], $sortorder, $file['width'], $sortorder, $file['height'], $sortorder);
break;
case 'dimensions':
array_multisort($file['dimensions'], $sortorder, $file['width'], $sortorder, $file['sortname'], SORT_ASC, $file['name'], SORT_ASC, $file['modified'], $sortorder, $file['type'], $sortorder, $file['size'], $sortorder, $file['height'], $sortorder);
break;
default:
// do nothing
}
}
/* Resize Image To Given Size */
function resizeimage($im, $maxwidth, $maxheight, $urlandname, $comp, $imagetype)
{
// security check
if (!file_in_dir($urlandname, $_SESSION['tinybrowser']['path']['root'])) {
deny(TB_NOT_IN_ALLOWED_DIR);
}
$width = imagesx($im);
$height = imagesy($im);
if (($maxwidth && $width > $maxwidth) || ($maxheight && $height > $maxheight)) {
if ($maxwidth && $width > $maxwidth) {
$widthratio = $maxwidth / $width;
$resizewidth = true;
} else $resizewidth = false;
if ($maxheight && $height > $maxheight) {
$heightratio = $maxheight / $height;
$resizeheight = true;
} else $resizeheight = false;
if ($resizewidth && $resizeheight) {
if ($widthratio < $heightratio) $ratio = $widthratio;
else $ratio = $heightratio;
} elseif ($resizewidth) {
$ratio = $widthratio;
} elseif ($resizeheight) {
$ratio = $heightratio;
}
$newwidth = $width * $ratio;
$newheight = $height * $ratio;
if (function_exists('imagecopyresampled') && $imagetype != 'image/gif') {
$newim = imagecreatetruecolor($newwidth, $newheight);
} else {
$newim = imagecreate($newwidth, $newheight);
}
// additional processing for png / gif transparencies (credit to Dirk Bohl)
if ($imagetype == 'image/x-png' || $imagetype == 'image/png') {
imagealphablending($newim, false);
imagesavealpha($newim, true);
} elseif ($imagetype == 'image/gif') {
$originaltransparentcolor = imagecolortransparent($im);
if ($originaltransparentcolor >= 0 && $originaltransparentcolor < imagecolorstotal($im)) {
$transparentcolor = imagecolorsforindex($im, $originaltransparentcolor);
$newtransparentcolor = imagecolorallocate($newim, $transparentcolor['red'], $transparentcolor['green'], $transparentcolor['blue']);
imagefill($newim, 0, 0, $newtransparentcolor);
imagecolortransparent($newim, $newtransparentcolor);
}
}
imagecopyresampled($newim, $im, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
if ($imagetype == 'image/pjpeg' || $imagetype == 'image/jpeg') {
imagejpeg($newim, $urlandname, $comp);
} elseif ($imagetype == 'image/x-png' || $imagetype == 'image/png') {
imagepng($newim, $urlandname, substr($comp, 0, 1));
} elseif ($imagetype == 'image/gif') {
imagegif($newim, $urlandname);
}
imagedestroy($newim);
} else {
if ($imagetype == 'image/pjpeg' || $imagetype == 'image/jpeg') {
imagejpeg($im, $urlandname, $comp);
} elseif ($imagetype == 'image/x-png' || $imagetype == 'image/png') {
imagepng($im, $urlandname, substr($comp, 0, 1));
} elseif ($imagetype == 'image/gif') {
imagegif($im, $urlandname);
}
}
}
/* Check Image Type And Convert To Temp Type */
function convert_image($imagetemp, $imagetype)
{
if ($imagetype == 'image/pjpeg' || $imagetype == 'image/jpeg') {
$cim1 = imagecreatefromjpeg($imagetemp);
} elseif ($imagetype == 'image/x-png' || $imagetype == 'image/png') {
$cim1 = imagecreatefrompng($imagetemp);
imagealphablending($cim1, false);
imagesavealpha($cim1, true);
} elseif ($imagetype == 'image/gif') {
$cim1 = imagecreatefromgif($imagetemp);
}
return $cim1;
}
/* Generate Form Open */
function form_open($name, $class, $url, $parameters)
{
?><form name="<?php echo filter_str($name); ?>" class="<?php echo filter_str($class); ?>" method="post" action="<?php echo filter_str($url . $parameters); ?>" accept-charset="utf-8">
<?php
}
/* Generate Form Select Element */
function form_select($options, $name, $label, $current, $auto)
{
if ($label) { ?><label for="<?php echo filter_str($name); ?>"><?php echo filter_str($label); ?></label><?php }
?><select name="<?php echo filter_str($name); ?>" <?php if ($auto) { ?>onchange="this.form.submit();"<?php } ?>>
<?php
$loopnum = count($options);
for ($i = 0; $i < $loopnum; $i++) {
$selected = ($options[$i][0] == $current ? ' selected' : '');
echo '<option value="' . filter_str($options[$i][0]) . '"' . $selected . '>' . $options[$i][1] . '</option>';
}
?></select><?php
}
/* Generate Form Hidden Element */
function form_hidden_input($name, $value)
{
?><input type="hidden" name="<?php echo filter_str($name); ?>" value="<?php echo filter_str($value); ?>" />
<?php
}
/* Generate Form Text Element */
function form_text_input($name, $label, $value, $size, $maxlength)
{
if ($label) { ?><label for="<?php echo filter_str($name); ?>"><?php echo filter_str($label); ?></label><?php } ?>
<input type="text" name="<?php echo filter_str($name); ?>" size="<?php echo filter_str($size); ?>"
maxlength="<?php echo filter_str($maxlength); ?>" value="<?php echo filter_str($value); ?>" /><?php
}
/* Generate Form Submit Button */
function form_submit_button($name, $label, $class)
{
?>
<button <?php if ($class) { ?>class="<?php echo filter_str($class); ?>"<?php } ?>type="submit"
name="<?php echo filter_str($name); ?>"><?php echo filter_str($label); ?></button>
</form>
<?php
}
/* Returns True if Number is Odd */
function IsOdd($num)
{
return (1 - ($num & 1));
}
/* Truncate Text to Given Length If Required */
function truncate_text($textstring, $length)
{
if (strlen($textstring) > $length) {
$textstring = substr($textstring, 0, $length) . '...';
}
return $textstring;
}
/* Present a size (in bytes) as a human-readable value */
function bytestostring($size, $precision = 0)
{
$sizes = array('YB', 'ZB', 'EB', 'PB', 'TB', 'GB', 'MB', 'KB', 'B');
$total = count($sizes);
while ($total-- && $size > 1024) $size /= 1024;
return round($size, $precision) . ' ' . $sizes[$total];
}
//function to clean a filename string so it is a valid filename
function clean_filename($filename)
{
$filename = stripslashesx($filename);
$filename = preg_replace('/^\W+|\W+$/', '', $filename); // remove all non-alphanumeric chars at begin & end of string
$filename = preg_replace('/\s+/', '_', $filename); // compress internal whitespace and replace with _
return strtolower(preg_replace('/\W-/', '', $filename)); // remove all non-alphanumeric chars except _ and -
}
function clean_dirname($dir)
{
$path = $dir;
$outpath = preg_replace("/\.[\.]+/", "", $path);
$outpath = preg_replace("/(%|~|\.\.|\.|\\\\|`|\/|\!|\@|\#|\^|&|\*|\(|\)|\;|\:|\"|\'|\|)/", "", $outpath);
$outpath = preg_replace("/^[\/]+/", "", $outpath);
$outpath = preg_replace("/^[A-Za-z][:\|][\/]?/", "", $outpath);
return $outpath;
}
/* Return File MIME Type */
function returnMIMEType($filename)
{
preg_match("|\.([a-z0-9]{2,4})$|i", $filename, $fileSuffix);
if (count($fileSuffix) < 2) return 'unknown/-';
switch (strtolower($fileSuffix[1])) {
case 'js' :
return 'application/x-javascript';
case 'json' :
return 'application/json';
case 'jpg' :
case 'jpeg' :
case 'jpe' :
return 'image/jpg';
case 'png' :
case 'gif' :
case 'bmp' :
case 'tiff' :
return 'image/' . strtolower($fileSuffix[1]);
case 'css' :
return 'text/css';
case 'xml' :
return 'application/xml';
case 'doc' :
case 'docx' :
return 'application/msword';
case 'xls' :
case 'xlt' :
case 'xlm' :
case 'xld' :
case 'xla' :
case 'xlc' :
case 'xlw' :
case 'xll' :
return 'application/vnd.ms-excel';
case 'ppt' :
case 'pps' :
return 'application/vnd.ms-powerpoint';
case 'rtf' :
return 'application/rtf';
case 'pdf' :
return 'application/pdf';
case 'html' :
case 'htm' :
case 'php' :
return 'text/html';
case 'txt' :
return 'text/plain';
case 'mpeg' :
case 'mpg' :
case 'mpe' :
return 'video/mpeg';
case 'mp3' :
return 'audio/mpeg3';
case 'wav' :
return 'audio/wav';
case 'aiff' :
case 'aif' :
return 'audio/aiff';
case 'avi' :
return 'video/msvideo';
case 'wmv' :
return 'video/x-ms-wmv';
case 'mov' :
return 'video/quicktime';
case 'zip' :
return 'application/zip';
case 'tar' :
return 'application/x-tar';
case 'swf' :
return 'application/x-shockwave-flash';
default :
if (function_exists('mime_content_type')) {
$fileSuffix = mime_content_type($filename);
}
return 'unknown/' . trim($fileSuffix[0], '.');
}
}
function sql_regcasex($str)
{
$ret = '';
for ($i = 0; $i < strlen($str); $i++) {
if ($str[$i] != '*' && $str[$i] != '.' && $str[$i] != ' ')
$ret .= '[' . strtoupper($str[$i]) . strtolower($str[$i]) . ']';
else
$ret .= $str[$i];
}
return $ret;
}
/* Return Array of Directory Structure */
function dirtree(&$alldirs, $types = '*.*', $root = '', $tree = '', $branch = '', $level = 0)
{
// filter file types according to type
$filetypes = explode(',', preg_replace('{[ \t]+}', '', $types));
if ($level == 0 && is_dir($root . $tree . $branch)) {
$filenum = 0;
foreach ($filetypes as $filetype) {
$filenum = $filenum + count(glob($root . $tree . $branch . sql_regcasex($filetype), GLOB_NOSORT));
}
$treeparts = explode('/', rtrim($tree, '/'));
$topname = end($treeparts);
$alldirs[] = array($branch, rtrim($topname, '/') . ' (' . $filenum . ')', rtrim($topname, '/'), rtrim($topname, '/'), $filenum, filemtime($root . $tree . $branch));
}
$level++;
$dh = opendir($root . $tree . $branch);
while (($dirname = readdir($dh)) !== false) {
if ($dirname != '.' && $dirname != '..' && is_dir($root . $tree . $branch . $dirname) && $dirname != '_thumbs') {
$filenum = 0;
foreach ($filetypes as $filetype) {
$filenum = $filenum + count(glob($root . $tree . $branch . $dirname . '/' . sql_regcasex($filetype), GLOB_NOSORT));
}
$indent = '';
for ($i = 0; $i < $level; $i++) {
$indent .= ' &nbsp; ';
}
if (strlen($indent) > 0) $indent .= '&rarr; ';
$alldirs[] = array(urlencode($branch . $dirname . '/'), $indent . $dirname . ' (' . $filenum . ')', $indent . $dirname, $dirname, $filenum, filemtime($root . $tree . $branch . $dirname));
dirtree($alldirs, $types, $root, $tree, $branch . $dirname . '/', $level);
}
}
closedir($dh);
$level--;
}
/* Return folder size in bytes (recursive) */
function get_folder_size($d = ".")
{
$h = @opendir($d);
if ($h == 0) return 0;
while ($f = readdir($h)) {
if ($f != "..") {
$sf += filesize($nd = $d . "/" . $f);
if ($f != "." && is_dir($nd)) {
$sf += get_folder_size($nd);
}
}
}
closedir($h);
return $sf;
}
/* Manage secure tokens to prevent CSFR */
function secure_tokens($check = true, $generate = true)
{
if ($_SESSION['tinybrowser']['debug_mode']) return;
no_cache();
if (session_id() != '') {
if ($check == true) {
if (!empty($_GET)) {
if (empty($_GET['tokenget']) || preg_match('/[a-f0-9]{32}/', $_GET['tokenget']) != true) {
echo 'NO GET TOKEN ' . TB_DENIED;
exit;
} else {
$find_token = array_search($_GET['tokenget'], $_SESSION['get_tokens']);
if ($find_token === false) {
echo 'INVALID GET TOKEN ' . TB_DENIED;
exit;
} else {
unset($_SESSION['get_tokens'][$find_token]);
}
}
}
if (!empty($_POST)) {
if (empty($_POST['tokenpost']) || preg_match('/[a-f0-9]{32}/', $_POST['tokenpost']) != true) {
echo 'NO POST TOKEN ' . TB_DENIED;
exit;
} else {
$find_token = array_search($_POST['tokenpost'], $_SESSION['post_tokens']);
if ($find_token === false) {
echo 'INVALID POST TOKEN ' . TB_DENIED;
exit;
} else {
unset($_SESSION['post_tokens'][$find_token]);
}
}
}
}
if ($generate == true) {
$_SESSION['get_tokens'][] = md5(uniqid(mt_rand(), true));
$_SESSION['post_tokens'][] = md5(uniqid(mt_rand(), true));
}
}
}
/* User defined error handling function. */
function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars)
{
// timestamp for the error entry.
$dt = date('Y-m-d H:i:s (T)');
// define an assoc array of error string
// in reality the only entries we should
// consider are E_WARNING, E_NOTICE, E_USER_ERROR,
// E_USER_WARNING and E_USER_NOTICE.
$errortype = array(
E_ERROR => 'Error',
E_WARNING => 'Warning',
E_PARSE => 'Parsing Error',
E_NOTICE => 'Notice',
E_CORE_ERROR => 'Core Error',
E_CORE_WARNING => 'Core Warning',
E_COMPILE_ERROR => 'Compile Error',
E_COMPILE_WARNING => 'Compile Warning',
E_USER_ERROR => 'User Error',
E_USER_WARNING => 'User Warning',
E_USER_NOTICE => 'User Notice',
E_STRICT => 'Runtime Notice'
);
// set of errors for which a var trace will be saved.
$user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);
if ($errno != E_STRICT) // exclude Runtime Notices
{
$err = $dt . "\t";
$err .= $errno . ' ' . $errortype[$errno] . "\t";
$err .= $errmsg . "\t";
$err .= 'File: ' . basename($filename) . "\t";
$err .= 'Line: ' . $linenum . "\t";
if (in_array($errno, $user_errors)) {
$err .= 'Trace: ' . wddx_serialize_value($vars, 'Variables') . "\t";
}
$err .= "\n";
// create error log if not exist
if (!file_exists($_SESSION['tinybrowser']['error_log_file'])) {
@fopen($_SESSION['tinybrowser']['error_log_file'], 'w');
}
// rotate log files
if (filesize($_SESSION['tinybrowser']['error_log_file']) > get_byte($_SESSION['tinybrowser']['error_log_file_max'])) {
if ($_SESSION['tinybrowser']['error_log_rotation']) {
$oldlog = str_replace('.log', '', $_SESSION['tinybrowser']['error_log_file']);
$oldlog = $oldlog . '_' . date("YmdHi") . '.log';
rename($_SESSION['tinybrowser']['error_log_file'], $oldlog);
} else {
unlink($_SESSION['tinybrowser']['error_log_file']);
}
}
error_log($err, 3, $_SESSION['tinybrowser']['error_log_file']);
}
if (!in_array($errno, array(E_NOTICE, E_STRICT))) {
die($err);
}
}
function set_language()
{
// Set language
if (isset($_SESSION['tinybrowser']['language']) && file_exists('langs/' . $_SESSION['tinybrowser']['language'] . '.php')) {
require_once('langs/' . $_SESSION['tinybrowser']['language'] . '.php');
} else {
require_once('langs/en.php'); // Falls back to English
}
}
function check_session_exists()
{
if ($_SESSION['tinybrowser']['debug_mode']) return;
// Check session exists
if (session_id() == '' || ($_SESSION['tinybrowser']['sessionsecured'] == false && basename($_SERVER['SCRIPT_NAME']) != 'tinybrowser.php')) {
echo TB_SESSDENIED;
exit;
}
// Check session variable exists
if ($_SESSION['tinybrowser']['sessionsecured'] == true && !isset($_SESSION[$_SESSION['tinybrowser']['sessioncheck']])) {
echo 'SESSION VARIABLE NOT SET ' . TB_DENIED;
exit;
}
}
function deny($msg)
{
$msg = str_ireplace($_SERVER['DOCUMENT_ROOT'], '', $msg);
header("Location: ?errmsg=" . $msg);
exit;
}
function no_cache()
{
if (!headers_sent()) {
session_cache_limiter('nocache');
header("Cache-Control: no-store,no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Mon, 26 Jul 1998 05:00:00 GMT"); // Date in the past
}
}
/*
Check the existence of upload dirs
if not exist, they will be created
*/
function check_upload_dirs()
{
// We first clear the stat cache
@clearstatcache();
if (!file_exists($_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path']['image'])) {
//sprintf(TB_UPLOADIRNOTCREATED,$_SESSION['tinybrowser']['path']['image']);
createfolder($_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path']['image'], $_SESSION['tinybrowser']['unixpermissions']);
}
if (!file_exists($_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path']['image'] . '_thumbs')) {
//sprintf(TB_UPLOADIRNOTCREATED,$_SESSION['tinybrowser']['path']['image'].'_thumbs');
createfolder($_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path']['image'] . '_thumbs', $_SESSION['tinybrowser']['unixpermissions']);
}
if (!file_exists($_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path']['media'])) {
//sprintf(TB_UPLOADIRNOTCREATED,$_SESSION['tinybrowser']['path']['media']);
createfolder($_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path']['media'], $_SESSION['tinybrowser']['unixpermissions']);
}
if (!file_exists($_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path']['file'])) {
//sprintf(TB_UPLOADIRNOTCREATED,$_SESSION['tinybrowser']['path']['file']);
createfolder($_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path']['file'], $_SESSION['tinybrowser']['unixpermissions']);
}
// Maybe we need to do additional checks for some reasons
if (!is_writeable($_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path']['image'])) {
sprintf(TB_UPLOADIRNOTWRITABLE, $_SESSION['tinybrowser']['path']['image']);
}
if (!is_writeable($_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path']['media'])) {
sprintf(TB_UPLOADIRNOTWRITABLE, $_SESSION['tinybrowser']['path']['media']);
}
if (!is_writeable($_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path']['file'])) {
sprintf(TB_UPLOADIRNOTWRITABLE, $_SESSION['tinybrowser']['path']['file']);
}
}
// Filter output strings using htmlentities with specified encoding in config file
function filter_str($str)
{
return htmlspecialchars($str, ENT_QUOTES, $_SESSION['tinybrowser']['encoding']);
}
/*
C$heck if file is in allowed dir
@return true|false
*/
function in_dir($input_dir, $allowed_dir)
{
$r = clean_dirslashes($input_dir);
$d = clean_dirslashes($allowed_dir);
$root = explode(DIRECTORY_SEPARATOR, realpath($d));
if (file_exists(urldecode($r))) {
$request = explode(DIRECTORY_SEPARATOR, realpath($r));
} else {
if (is_file($r)) {
$request = explode(DIRECTORY_SEPARATOR, dirname($r));
} else {
$request = explode(DIRECTORY_SEPARATOR, $r);
}
}
empty ($request [0]) ? array_shift($request) : $request;
empty ($root [0]) ? array_shift($root) : $root;
if (count(array_diff_assoc($root, $request)) > 0) {
return false;
}
return true;
}
function file_in_dir($input_file, $allowed_dir)
{
$dir = clean_dirslashes(dirname(stripslashesx($input_file)));
$dir_top = clean_dirslashes($allowed_dir);
if ($dir == $dir_top)
return true;
$dir = realpath($dir);
$dir_top = realpath($dir_top);
$dir = count(explode(DIRECTORY_SEPARATOR, $dir));
$dir_top = count(explode(DIRECTORY_SEPARATOR, $dir_top));
if ($dir <= $dir_top)
return false;
return true;
}
function clean_dirslashes($s)
{
if (!preg_match("/(\/|\\\)$/", $s))
$s = $s . DIRECTORY_SEPARATOR;
$s = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $s);
return $s;
}
function stripslashesx($s)
{
return (get_magic_quotes_gpc()) ? stripslashes($s) : $s;
}
function parse_size($s)
{
preg_match("/(\d{1,}+)(\w+)/", $s, $p);
if (count($p) == 3) {
return array($p[1], $p[2]);
} else {
preg_match("/(\d{1,}+)\s(\w+)/", $s, $p);
if (count($p) == 3) {
return array($p[1], $p[2]);
}
}
}
function get_byte($raw)
{
// $raw : '500kb', '1mb'
require_once('lib/byte_converter.class.php');
$file_raw_size = parse_size($raw);
$size_in_byte = 0;
try {
$byte = new byte_converter;
$byte->set_limit("tb"); //show types up to tera byte
$file_size = $byte->auto($file_raw_size[0], $file_raw_size[1]);
$size_in_byte = $file_size['b'];
} catch (Exception $e) {
echo $e;
}
return $size_in_byte;
}
function dirsize($directory)
{
$size = 0;
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)) as $file) {
$size += $file->getSize();
}
return $size;
}
function verify_dir($dir, $type = 'root')
{
if (is_array($dir)) {
foreach ($dir as $d) {
if (strlen($d) != 0 || $d != '') {
if (!in_dir($d, $_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path'][$type])) deny(TB_NOT_IN_ALLOWED_DIR . ' : ' . $_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path'][$type]);
}
}
} else {
if (strlen($dir) == 0 || $dir == '')
return;
if (!in_dir($dir, $_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path'][$type])) deny(TB_NOT_IN_ALLOWED_DIR . ' : ' . $_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path'][$type]);
}
}
// make sure requested file is in allowed dir
function verify_file($file, $type = 'root', $check_exists = false)
{
if (is_array($file)) {
foreach ($file as $f) {
if (!file_in_dir($f, $_SESSION['tinybrowser']['path'][$type])) deny(TB_NOT_IN_ALLOWED_DIR);
if ($check_exists) {
if (!file_exists($f)) deny(TB_NOT_EXISTS);
}
}
} else {
if (!file_in_dir($file, $_SESSION['tinybrowser']['path'][$type])) deny(TB_NOT_IN_ALLOWED_DIR);
if ($check_exists) {
if (!file_exists($file)) deny(TB_NOT_EXISTS);
}
}
}
function sanitize_dir($dir)
{
$dir = stripslashes($dir);
// . \ / | : ? * " < >
$dir = preg_replace('/\\.|\\\\|\\||\\:|\\?|\\*|"|<|>|[[:cntrl:]]/', '', $dir);
$dir = str_replace("//", "", $dir);
return $dir;
}
function has_bad_utf8($string)
{
$regex =
'([\x00-\x7F]' .
'|[\xC2-\xDF][\x80-\xBF]' .
'|\xE0[\xA0-\xBF][\x80-\xBF]' .
'|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}' .
'|\xED[\x80-\x9F][\x80-\xBF]' .
'|\xF0[\x90-\xBF][\x80-\xBF]{2}' .
'|[\xF1-\xF3][\x80-\xBF]{3}' .
'|\xF4[\x80-\x8F][\x80-\xBF]{2}' .
'|(.{1}))';
while (preg_match('/' . $regex . '/S', $string, $matches)) {
if (isset($matches[2])) {
return true;
}
$string = substr($string, strlen($matches[0]));
}
return false;
}
function is_dir_empty($dir)
{
if (is_dir($dir))
return (count(glob("$dir/*")) === 0) ? true : false;
}
if ($_SESSION['tinybrowser']['tb_log_error']) $old_error_handler = set_error_handler('userErrorHandler');
if ($_SESSION['tinybrowser']['debug_mode']) {
$_SESSION['get_tokens'][] = md5(uniqid(mt_rand(), true));
$_SESSION['post_tokens'][] = md5(uniqid(mt_rand(), true));
}
?>
<?php
require_once('config_tinybrowser.php');
require_once('fns_tinybrowser.php');
// Set language
set_language();
// Set default encoding type
if (!headers_sent()) {
header("Content-Type: text/html; charset={$_SESSION['tinybrowser']['encoding']}");
}
// Check and generate request tokens
secure_tokens();
// Check session exists
check_session_exists();
if (!$_SESSION['tinybrowser']['allowupload']) {
deny(TB_UPDENIED);
}
// Assign get variables
$typenow = ((isset($_GET['type']) && in_array($_GET['type'], $_SESSION['tinybrowser']['valid']['type'])) ? $_GET['type'] : 'image');
$foldernow = str_replace(array('../', '..\\', '..', './', '.\\'), '', ($_SESSION['tinybrowser']['allowfolders'] && isset($_REQUEST['folder']) ? urldecode($_REQUEST['folder']) : ''));
$passfolder = '&folder=' . urlencode($foldernow);
$passfeid = (!empty($_GET['feid']) && preg_match("/^[a-zA-Z0-9_\-]+$/", $_GET['feid']) == true ? '&feid=' . $_GET['feid'] : '');
$passupfeid = (!empty($_GET['feid']) && preg_match("/^[a-zA-Z0-9_\-]+$/", $_GET['feid']) == true ? $_GET['feid'] : '');
$tokenget = !empty($_SESSION['get_tokens']) ? '&tokenget=' . end($_SESSION['get_tokens']) : '';
// Assign upload path
if (strpos($foldernow, $_SESSION['tinybrowser']['path'][$typenow]) == 1) {
$uploadpath = urlencode($_SESSION['tinybrowser']['path'][$typenow] . $foldernow);
} else {
$uploadpath = urlencode($_SESSION['tinybrowser']['path'][$typenow]);
}
verify_dir($_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path'][$typenow] . $foldernow, $typenow);
// Assign directory structure to array
$uploaddirs = array();
dirtree($uploaddirs, $_SESSION['tinybrowser']['filetype'][$typenow], $_SESSION['tinybrowser']['docroot'], $_SESSION['tinybrowser']['path'][$typenow]);
// determine file dialog file types
switch ($typenow) {
case 'image':
$filestr = TB_TYPEIMG;
break;
case 'media':
$filestr = TB_TYPEMEDIA;
break;
case 'file':
$filestr = TB_TYPEFILE;
break;
}
$fileexts = str_replace(",", ";", $_SESSION['tinybrowser']['filetype'][$typenow]);
$filelist = $filestr . ' (' . $_SESSION['tinybrowser']['filetype'][$typenow] . ')';
// Initalise alert array
$notify = array(
'type' => array(),
'message' => array()
);
$goodqty = (!empty($_GET['goodfiles']) && is_numeric($_GET['goodfiles']) && $_GET['goodfiles'] > 0 ? (int)$_GET['goodfiles'] : 0);
$badqty = (!empty($_GET['badfiles']) && is_numeric($_GET['badfiles']) && $_GET['badfiles'] > 0 ? (int)$_GET['badfiles'] : 0);
$dupqty = (!empty($_GET['dupfiles']) && is_numeric($_GET['dupfiles']) && $_GET['dupfiles'] > 0 ? (int)$_GET['dupfiles'] : 0);
if ($goodqty > 0) {
$notify['type'][] = 'success';
$notify['message'][] = sprintf(TB_MSGUPGOOD, $goodqty);
}
if ($badqty > 0) {
$notify['type'][] = 'failure';
$notify['message'][] = sprintf(TB_MSGUPBAD, $badqty);
}
if ($dupqty > 0) {
$notify['type'][] = 'failure';
$notify['message'][] = sprintf(TB_MSGUPDUP, $dupqty);
}
if (isset($_GET['permerror'])) {
$notify['type'][] = 'failure';
$notify['message'][] = sprintf(TB_MSGUPFAIL, $_SESSION['tinybrowser']['path'][$typenow]);
}
// Check files/folder quota size limitt
if ($_SESSION['tinybrowser']['quota_check']) {
$foldersize = dirsize($_SESSION['tinybrowser']['docroot'] . $_SESSION['tinybrowser']['path'][$typenow]);
// is folder size within quota size limit?
if ($foldersize > get_byte($_SESSION['tinybrowser']['max_quota'])) {
$notify['type'][] = 'failure';
$notify['message'][] = TB_MSGMAXQUOTA;
$disableupload = true;
if ($_SESSION['tinybrowser']['max_quota_notified']) {
$notified_subj = $_SERVER['SERVER_NAME'] . ' Folder Size Exceeded';
$notified_message = <<<EOL
Dear WebMaster
The size of upload location: {$_SESSION['tinybrowser']['path']} has exceeded the quota limit: {$_SESSION['tinybrowser']['max_quota']}.
Solution #1 Please increase the quota size.
Solution #2 Please check, and remove unnecessary junk data.
To disable this notification, set \$_SESSION['tinybrowser']['max_quota_notified'] to false in config_tinybrowser.php.
Regards
TinyBrowser Notifier
EOL;
@mail($_SESSION['tinybrowser']['webmaster_email'], $notified_subj, $notified_message, null);
}
} else
$disableupload = false;
} else
$disableupload = false;
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>TinyBrowser :: <?= TB_UPLOAD; ?></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Pragma" content="no-cache"/>
<?php
if ($passfeid == '' && $_SESSION['tinybrowser']['integration'] == 'tinymce') {
?>
<link rel="stylesheet" type="text/css" media="all" href="<?= $_SESSION['tinybrowser']['tinymcecss']; ?>" /><?php
} else {
?>
<link rel="stylesheet" type="text/css" media="all" href="css/stylefull_tinybrowser.css"/><?php
}
?>
<link rel="stylesheet" type="text/css" media="all" href="css/style_tinybrowser.css.php"/>
<script type="text/javascript" src="/public/scripts/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
function uploadComplete(url) {
document.location = url;
}
</script>
</head>
<?php
if ($disableupload == false)
{ ?>
<body>
<?php }
else
{ ?>
<body>
<?php }
if (isset($_GET['errmsg'])) {
$notify['type'][] = 'failure';
$notify['message'][] = sprintf(htmlspecialchars($_GET['errmsg'], ENT_QUOTES, $_SESSION['tinybrowser']['encoding']), $errorqty);
}
if (count($notify['type']) > 0) alert($notify);
form_open('foldertab', false, 'upload.php', '?type=' . $typenow . $tokenget . $passfeid);
?>
<div class="tabs">
<ul>
<li id="browse_tab"><span><a
href="tinybrowser.php?type=<?= $typenow . $tokenget . $passfolder . $passfeid; ?>"><?= TB_BROWSE; ?></a></span>
</li>
<li id="upload_tab" class="current"><span><a
href="upload.php?type=<?= $typenow . $tokenget . $passfolder . $passfeid; ?>"><?= TB_UPLOAD; ?></a></span>
</li>
<?php
if ($_SESSION['tinybrowser']['allowedit'] || $_SESSION['tinybrowser']['allowdelete']) {
?>
<li id="edit_tab"><span><a
href="edit.php?type=<?= $typenow . $tokenget . $passfolder . $passfeid; ?>"><?= TB_EDIT; ?></a></span>
</li>
<?php
}
if ($_SESSION['tinybrowser']['allowfolders']) {
?>
<li id="folders_tab"><span><a
href="folders.php?type=<?= $typenow . $tokenget . $passfolder . $passfeid; ?>"><?= TB_FOLDERS; ?></a></span>
</li><?php
// Display folder select, if multiple exist
if (count($uploaddirs) > 1) {
?>
<li id="folder_tab" class="right"><span><?php
form_select($uploaddirs, 'folder', TB_FOLDERCURR, urlencode($foldernow), true);
if (!empty($_SESSION['post_tokens'])) form_hidden_input('tokenpost', end($_SESSION['post_tokens']));
?></span></li><?php
}
}
?>
</ul>
</div>
<div class="panel_wrapper">
<div id="general_panel" class="panel currentmod">
<fieldset>
<legend><?= TB_UPLOADFILE; ?></legend>
<form enctype="multipart/form-data" id="upload_form" action="">
<input type="file" id="file" name="Filedata"/>
<input type="submit" id="submit_form"/>
</form>
<div id="upload-result"></div>
<script type="text/javascript">
$(document).ready(function () {
$("#submit_form").click(function (e) {
e.preventDefault();
$("#upload-result").html('');
var formData = new FormData();
formData.append('Filedata', $('#file')[0].files[0]);
$.ajax({
url: "/public/tiny_mce/plugins/tinybrowser/upload_file.php?obfuscate=<?= end($_SESSION['get_tokens']); ?>&type=<?= $typenow; ?>&folder=<?= urlencode($uploadpath); ?>",
type: 'POST',
data: formData,
processData: false, // tell jQuery not to process the data
contentType: false, // tell jQuery not to set contentType
}).done(function (message) {
$("#upload-result").html(message);
}).fail(function (jqXHR, textStatus, errorThrown) {
$("#upload-result").html(jqXHR.responseText);
});
});
});
</script>
</fieldset>
</div>
</div>
</body>
</html>
<?php
require_once('config_tinybrowser.php');
require_once('fns_tinybrowser.php');
// Set language
set_language();
// Check session exists
check_session_exists();
// Assign get variables
$typenow = ((isset($_GET['type']) && in_array($_GET['type'], $_SESSION['tinybrowser']['valid']['type'])) ? $_GET['type'] : 'image');
$folder = $_SESSION['tinybrowser']['docroot'] . urldecode($_GET['folder']);
$foldernow = urlencode(str_replace($_SESSION['tinybrowser']['path'][$typenow], '', urldecode($_GET['folder'])));
$errors = array();
if (!$_SESSION['tinybrowser']['allowupload']) {
$errors[] = TB_UPDENIED;
}
// security check
verify_dir(array($folder, $foldernow), $typenow);
// Check request token
if (!$_SESSION['tinybrowser']['debug_mode']) {
$find_token = array_search($_GET['obfuscate'], $_SESSION['get_tokens']);
if ($find_token === false) {
$errors[] = TB_DENIED;
}
}
// Check and assign get variables
if (isset($_GET['type']) && in_array($_GET['type'], $_SESSION['tinybrowser']['valid']['type'])) {
$typenow = $_GET['type'];
} else {
$errors[] = TB_INVALID_FILETYPE;
}
$dest_folder = null;
if (isset($_GET['folder'])) {
$dest_folder = urldecode($_GET['folder']);
} else {
$errors[] = TB_NOT_IN_ALLOWED_DIR;
}
// Check file extension isn't prohibited
$nameparts = explode('.', $_FILES['Filedata']['name']);
$ext = end($nameparts);
if (!validateExtension($ext, $_SESSION['tinybrowser']['prohibited'])) {
$errors[] = TB_FORBIDDEN_FILEXT;
}
if (strpos($_SESSION['tinybrowser']['filetype'][$typenow], $ext) === false) {
$errors[] = TB_FORBIDDEN_FILEXT;
}
// Check file size
if (isset($_FILES['Filedata']['size']) && $_FILES['Filedata']['size'] > get_byte($_SESSION['tinybrowser']['maxsize'][$typenow])) {
$errors[] = TB_MSGMAXSIZE;
}
if ($_SESSION['tinybrowser']['debug_mode'] && !empty($_SESSION['tinybrowser']['webmaster_email'])) {
$msg = "ERRORS: " . print_r($errors, true) . "\n\nPOST: " . print_r($_GET, true) . "\n\nGET: " . print_r($_GET, true) . "\n\nSESSION: " . print_r($_SESSION, true);
mail($_SESSION['tinybrowser']['webmaster_email'], 'TinyBrowser File Upload Attempt', $msg);
if (!empty($errors)) exit;
}
if (!empty($errors)) {
header('HTTP/1.1 409 Conflict');
foreach ($errors as $error) {
echo '<p>' . $error . '</p>';
}
exit;
}
// Check file data
$success = false;
if ($_FILES['Filedata']['tmp_name'] && $_FILES['Filedata']['name']) {
$source_file = $_FILES['Filedata']['tmp_name'];
$file_name = stripslashes($_FILES['Filedata']['name']);
if ($_SESSION['tinybrowser']['cleanfilename']) $file_name = clean_filename($file_name);
verify_dir($_SESSION['tinybrowser']['docroot'] . $dest_folder);
if (is_dir($_SESSION['tinybrowser']['docroot'] . $dest_folder)) {
$success = copy($source_file, $_SESSION['tinybrowser']['docroot'] . $dest_folder . '/' . $file_name . '_');
}
}
if (!$success) {
header('HTTP/1.1 500 Internal Server Error');
echo '<p>Internal Server Error</p>';
}
if ($_SESSION['tinybrowser']['delayprocess'] > 0) {
sleep($_SESSION['tinybrowser']['delayprocess']);
}
if ($handle = opendir($folder)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".." && substr($file, -1) == '_') {
//-- File Naming
$tmp_filename = $folder . $file;
$dest_filename = $folder . rtrim($file, '_');
//-- Duplicate Files
if (file_exists($dest_filename)) {
unlink($tmp_filename);
continue;
}
//-- Bad extensions
$nameparts = explode('.', $dest_filename);
$ext = end($nameparts);
if (!validateExtension($ext, $_SESSION['tinybrowser']['prohibited'])) {
unlink($tmp_filename);
continue;
}
// -- Allow only certain extension; otherwise remove tmp file
if (strpos($_SESSION['tinybrowser']['filetype'][$typenow], $ext) < 0) {
unlink($tmp_filename);
continue;
}
//-- Rename temp file to dest file
rename($tmp_filename, $dest_filename);
//-- if image, perform additional processing
if ($typenow == 'image') {
//-- Good mime-types
$imginfo = getimagesize($dest_filename);
if ($imginfo === false) {
unlink($dest_filename);
continue;
}
$mime = $imginfo['mime'];
// resize image to maximum height and width, if set
if ($_SESSION['tinybrowser']['imageresize']['width'] > 0 || $_SESSION['tinybrowser']['imageresize']['height'] > 0) {
// assign new width and height values, only if they are less than existing image size
$widthnew = ($_SESSION['tinybrowser']['imageresize']['width'] > 0 && $_SESSION['tinybrowser']['imageresize']['width'] < $imginfo[0] ? $_SESSION['tinybrowser']['imageresize']['width'] : $imginfo[0]);
$heightnew = ($_SESSION['tinybrowser']['imageresize']['height'] > 0 && $_SESSION['tinybrowser']['imageresize']['height'] < $imginfo[1] ? $_SESSION['tinybrowser']['imageresize']['height'] : $imginfo[1]);
// only resize if width or height values are different
if ($widthnew != $imginfo[0] || $heightnew != $imginfo[1]) {
$im = convert_image($dest_filename, $mime);
resizeimage($im, $widthnew, $heightnew, $dest_filename, $_SESSION['tinybrowser']['imagequality'], $mime);
imagedestroy($im);
}
}
// generate thumbnail
$thumbimg = $folder . '_thumbs/_' . rtrim($file, '_');
if (!file_exists($thumbimg)) {
$im = convert_image($dest_filename, $mime);
resizeimage($im, $_SESSION['tinybrowser']['thumbsize'], $_SESSION['tinybrowser']['thumbsize'], $thumbimg, $_SESSION['tinybrowser']['thumbquality'], $mime);
imagedestroy($im);
}
}
}
}
closedir($handle);
}
header('HTTP/1.1 200 Success');
echo '<p>File Upload Succeeded</p>';
@akotulu
Copy link
Author

akotulu commented Dec 1, 2020

File upload_process.php can be removed, code has been migrated to upload_file.php.

@Jim-leon
Copy link

Jim-leon commented Jan 6, 2021

Hello,
Excellent script and just what I require to solve this issue. However what is the verify_dir function you included? Doesn't seem to be a native function and it's not define anywhere in the code.
Jim

@akotulu
Copy link
Author

akotulu commented Jan 6, 2021

Hello,
Excellent script and just what I require to solve this issue. However what is the verify_dir function you included? Doesn't seem to be a native function and it's not define anywhere in the code.
Jim

Hey, function should be declared in tiny_mce/plugins/tinybrowser/fns_tinybrowser.php file.
I will include the file here, if you don't have it.

@Jim-leon
Copy link

Jim-leon commented Jan 6, 2021 via email

@DrLove73
Copy link

Hi. I downloaded and replaced the 3 files on tinybrowser 1.41 from 2008, but When I try to open upload window it only writes "NO GET TOKEN You require permission to view this page."
What I am doing wrong?

@akotulu
Copy link
Author

akotulu commented Jan 13, 2021

I have no idea, the source code for tinybrowser does not contain this message.

@DrLove73
Copy link

DrLove73 commented Jan 13, 2021

As I have deduced, it is trigered by /* Manage secure tokens to prevent CSFR */ (fns_tinybrowser.php line 413)

This code in uploads.php:

// Check and generate request tokens
secure_tokens();

calls the function in fns_tinybrowser.php, but for some reason line 421 is trigered and TB_DENIED is raised.

@ceesvanegmond
Copy link

@akotulu on which version of tinybrowser is this fix working?

@akotulu
Copy link
Author

akotulu commented Apr 7, 2021

@ceesvanegmond

majorVersion: 3
minorVersion: 4b1
releaseDate: 2010-12-20

@JonWallsten
Copy link

For anyone else coming here confused:
Version is 1.42 and seems to be tricky to find.
I took it from here:
https://github.com/flikQ/rocketeercms/tree/master/themes/admin/assets/js/tiny_mce/plugins/tinybrowser

@Jimmi08
Copy link

Jimmi08 commented Dec 17, 2021

Thank you so much for this. It fixed PHP 7 issues too.

@Jacu77
Copy link

Jacu77 commented Nov 14, 2022

Hi. Thanks for your work. Anyway trying to UPLOAD a file I have a problem :(
My browser says: Error too many redirections.
Does anyone have such an error? How to fix it? :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment