]> git.p6c8.net - jirafeau.git/blobdiff - lib/functions.php
[BUGFIX] Limit upload chunk size to a reasonable value
[jirafeau.git] / lib / functions.php
index e72359e6d965b7d6406242f25eefd765700122bf..4dcf5de235f94cb35c5670c17a495c8e26d51c93 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 /**
  */
 
 /**
- * Transform a string in a path by seperating each letters by a '/'.
+ * Transform a string in a path by separating each letters by a '/'.
  * @return path finishing with a '/'
  */
 function s2p($s)
  * @return path finishing with a '/'
  */
 function s2p($s)
@@ -28,7 +28,7 @@ function s2p($s)
     $block_size = 8;
     $p = '';
     for ($i = 0; $i < strlen($s); $i++) {
     $block_size = 8;
     $p = '';
     for ($i = 0; $i < strlen($s); $i++) {
-        $p .= $s{$i};
+        $p .= $s[$i];
         if (($i + 1) % $block_size == 0) {
             $p .= '/';
         }
         if (($i + 1) % $block_size == 0) {
             $p .= '/';
         }
@@ -68,16 +68,16 @@ function base_16_to_64($num)
     # Convert long hex string to bin.
     $size = strlen($num);
     for ($i = 0; $i < $size; $i++) {
     # Convert long hex string to bin.
     $size = strlen($num);
     for ($i = 0; $i < $size; $i++) {
-        $b .= $hex2bin{hexdec($num{$i})};
+        $b .= $hex2bin[hexdec($num[$i])];
     }
     # Convert long bin to base 64.
     $size *= 4;
     for ($i = $size - 6; $i >= 0; $i -= 6) {
     }
     # Convert long bin to base 64.
     $size *= 4;
     for ($i = $size - 6; $i >= 0; $i -= 6) {
-        $o = $m{bindec(substr($b, $i, 6))} . $o;
+        $o = $m[bindec(substr($b, $i, 6))] . $o;
     }
     # Some few bits remaining ?
     if ($i < 0 && $i > -6) {
     }
     # Some few bits remaining ?
     if ($i < 0 && $i > -6) {
-        $o = $m{bindec(substr($b, 0, $i + 6))} . $o;
+        $o = $m[bindec(substr($b, 0, $i + 6))] . $o;
     }
     return $o;
 }
     }
     return $o;
 }
@@ -229,6 +229,21 @@ function jirafeau_get_max_upload_size()
     return jirafeau_human_size(jirafeau_get_max_upload_size_bytes());
 }
 
     return jirafeau_human_size(jirafeau_get_max_upload_size_bytes());
 }
 
+/**
+ * get the maximal upload size for a data chunk in async uploads
+ * @param max_upload_chunk_size_bytes
+ */
+function jirafeau_get_max_upload_chunk_size_bytes($max_upload_chunk_size_bytes = 0)
+{
+    if ($max_upload_chunk_size_bytes > 0) {
+        return min(
+            jirafeau_get_max_upload_size_bytes(),
+            $max_upload_chunk_size_bytes
+        );
+    }
+    return jirafeau_get_max_upload_size_bytes();
+}
+
 /**
  * gets a string explaining the error
  * @param $code the error code
 /**
  * gets a string explaining the error
  * @param $code the error code
@@ -418,7 +433,7 @@ function jirafeau_upload($file, $one_time_download, $key, $time, $ip, $crypt, $l
         }
     }
 
         }
     }
 
-    /* file informations */
+    /* file information */
     $hash = jirafeau_hash_file($file_hash_method, $file['tmp_name']);
     $name = str_replace(NL, '', trim($file['name']));
     $mime_type = $file['type'];
     $hash = jirafeau_hash_file($file_hash_method, $file['tmp_name']);
     $name = str_replace(NL, '', trim($file['name']));
     $mime_type = $file['type'];
@@ -509,10 +524,15 @@ function jirafeau_upload($file, $one_time_download, $key, $time, $ip, $crypt, $l
 function jirafeau_is_viewable($mime)
 {
     if (!empty($mime)) {
 function jirafeau_is_viewable($mime)
 {
     if (!empty($mime)) {
-        /* Actually, verify if mime-type is an image or a text. */
-        $viewable = array('image', 'text', 'video', 'audio');
+        $viewable = array('image', 'video', 'audio');
         $decomposed = explode('/', $mime);
         $decomposed = explode('/', $mime);
-        return in_array($decomposed[0], $viewable);
+        if (in_array($decomposed[0], $viewable) && strpos($mime, 'image/svg+xml') === false) {
+            return true;
+        }
+        $viewable = array('text/plain');
+        if (in_array($mime, $viewable)) {
+            return true;
+        }
     }
     return false;
 }
     }
     return false;
 }
@@ -588,8 +608,8 @@ function check_errors($cfg)
 }
 
 /**
 }
 
 /**
- * Read link informations
- * @return array containing informations.
+ * Read link information
+ * @return array containing information.
  */
 function jirafeau_get_link($hash)
 {
  */
 function jirafeau_get_link($hash)
 {
@@ -654,7 +674,7 @@ function jirafeau_admin_list($name, $file_hash, $link_hash)
                 /* Push new found directory. */
                 $stack[] = $d . $node . '/';
             } elseif (is_file($d . $node)) {
                 /* Push new found directory. */
                 $stack[] = $d . $node . '/';
             } elseif (is_file($d . $node)) {
-                /* Read link informations. */
+                /* Read link information. */
                 $l = jirafeau_get_link($node);
                 if (!count($l)) {
                     continue;
                 $l = jirafeau_get_link($node);
                 if (!count($l)) {
                     continue;
@@ -670,7 +690,7 @@ function jirafeau_admin_list($name, $file_hash, $link_hash)
                 if (!empty($link_hash) && $link_hash != $node) {
                     continue;
                 }
                 if (!empty($link_hash) && $link_hash != $node) {
                     continue;
                 }
-                /* Print link informations. */
+                /* Print link information. */
                 echo '<tr>';
                 echo '<td>' .
                 '<strong><a id="upload_link" href="f.php?h='. jirafeau_escape($node) .'" title="' .
                 echo '<tr>';
                 echo '<td>' .
                 '<strong><a id="upload_link" href="f.php?h='. jirafeau_escape($node) .'" title="' .
@@ -732,7 +752,7 @@ function jirafeau_admin_clean()
                 /* Push new found directory. */
                 $stack[] = $d . $node . '/';
             } elseif (is_file($d . $node)) {
                 /* Push new found directory. */
                 $stack[] = $d . $node . '/';
             } elseif (is_file($d . $node)) {
-                /* Read link informations. */
+                /* Read link information. */
                 $l = jirafeau_get_link(basename($node));
                 if (!count($l)) {
                     continue;
                 $l = jirafeau_get_link(basename($node));
                 if (!count($l)) {
                     continue;
@@ -752,7 +772,7 @@ function jirafeau_admin_clean()
 
 
 /**
 
 
 /**
- * Clean old async transferts.
+ * Clean old async transfers.
  * @return number of cleaned files.
  */
 function jirafeau_admin_clean_async()
  * @return number of cleaned files.
  */
 function jirafeau_admin_clean_async()
@@ -773,12 +793,12 @@ function jirafeau_admin_clean_async()
                 /* Push new found directory. */
                 $stack[] = $d . $node . '/';
             } elseif (is_file($d . $node)) {
                 /* Push new found directory. */
                 $stack[] = $d . $node . '/';
             } elseif (is_file($d . $node)) {
-                /* Read async informations. */
+                /* Read async information. */
                 $a = jirafeau_get_async_ref(basename($node));
                 if (!count($a)) {
                     continue;
                 }
                 $a = jirafeau_get_async_ref(basename($node));
                 if (!count($a)) {
                     continue;
                 }
-                /* Delete transferts older than 1 hour. */
+                /* Delete transfers older than 1 hour. */
                 if (time() - $a['last_edited'] > 3600) {
                     jirafeau_async_delete(basename($node));
                     $count++;
                 if (time() - $a['last_edited'] > 3600) {
                     jirafeau_async_delete(basename($node));
                     $count++;
@@ -830,7 +850,8 @@ function jirafeau_admin_bug_report($cfg)
         'enable_crypt',
         'preview',
         'maximal_upload_size',
         'enable_crypt',
         'preview',
         'maximal_upload_size',
-        'store_uploader_ip'
+        'store_uploader_ip',
+        'max_upload_chunk_size_bytes'
     ];
     foreach ($jirafeau_options as &$o) {
         $v = $cfg[$o];
     ];
     foreach ($jirafeau_options as &$o) {
         $v = $cfg[$o];
@@ -843,12 +864,16 @@ function jirafeau_admin_bug_report($cfg)
     $out .= "- mcrypt version: " . phpversion('mcrypt') . "<br/>";
     $php_options =  [
         'post_max_size',
     $out .= "- mcrypt version: " . phpversion('mcrypt') . "<br/>";
     $php_options =  [
         'post_max_size',
-        'upload_max_filesize'
+        'upload_max_filesize',
+        'safe_mode',
+        'max_execution_time',
+        'max_input_time'
     ];
     foreach ($php_options as &$o) {
         $v = ini_get($o);
         $out .= "- $o: " . jirafeau_strval($v) . " (" . gettype($v). ")<br/>";
     }
     ];
     foreach ($php_options as &$o) {
         $v = ini_get($o);
         $out .= "- $o: " . jirafeau_strval($v) . " (" . gettype($v). ")<br/>";
     }
+    $out .= "- can set_time_limit: " . (set_time_limit(0) ? "yes" : "no") . "<br/>";
     $out .= "<br/>";
 
     $out .= "# File permissions<br/>";
     $out .= "<br/>";
 
     $out .= "# File permissions<br/>";
@@ -869,17 +894,22 @@ function jirafeau_admin_bug_report($cfg)
     $out .= "# Browser details<br/>";
     $out .= "<script type='text/javascript' lang='Javascript'>
         // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
     $out .= "# Browser details<br/>";
     $out .= "<script type='text/javascript' lang='Javascript'>
         // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
-        document.write('- HTML5 support: ' + (check_html5_file_api() ? 'yes' : 'no') + '<br/>');
-        document.write('- User agent: ' + navigator.userAgent + '<br/>');
+        document.write('- html5 support: ' + (check_html5_file_api() ? 'yes' : 'no') + '<br/>');
+        document.write('- user agent: ' + navigator.userAgent + '<br/>');
         // @license-end
         </script>";
         // @license-end
         </script>";
+    $out .= "<br/>";
+
+    $out .= "# Memory<br/>";
+    $out .= "- memory_get_peak_usage: " . jirafeau_human_size(memory_get_peak_usage()) . "<br/>";
+
     $out .= "</code></fieldset>";
     return $out;
 }
 
 /**
     $out .= "</code></fieldset>";
     return $out;
 }
 
 /**
- * Read async transfert informations
- * @return array containing informations.
+ * Read async transfer information
+ * @return array containing information.
  */
 function jirafeau_get_async_ref($ref)
 {
  */
 function jirafeau_get_async_ref($ref)
 {
@@ -903,7 +933,7 @@ function jirafeau_get_async_ref($ref)
 }
 
 /**
 }
 
 /**
- * Delete async transfert informations
+ * Delete async transfer information
  */
 function jirafeau_async_delete($ref)
 {
  */
 function jirafeau_async_delete($ref)
 {
@@ -927,17 +957,15 @@ function jirafeau_async_delete($ref)
 
 /**
   * Init a new asynchronous upload.
 
 /**
   * Init a new asynchronous upload.
-  * @param $finename Name of the file to send
+  * @param $filename Name of the file to send
   * @param $one_time One time upload parameter
   * @param $key eventual password (or blank)
   * @param $time time limit
   * @param $ip ip address of the client
   * @param $one_time One time upload parameter
   * @param $key eventual password (or blank)
   * @param $time time limit
   * @param $ip ip address of the client
-  * @return a string containing a temporary reference followed by a code or the string 'Error'
+  * @return a string containing a temporary reference followed by a code or a string starting with 'Error'
   */
 function jirafeau_async_init($filename, $type, $one_time, $key, $time, $ip)
 {
   */
 function jirafeau_async_init($filename, $type, $one_time, $key, $time, $ip)
 {
-    $res = 'Error';
-
     /* Create temporary folder. */
     $ref;
     $p;
     /* Create temporary folder. */
     $ref;
     $p;
@@ -948,8 +976,7 @@ function jirafeau_async_init($filename, $type, $one_time, $key, $time, $ip)
     } while (file_exists($p));
     @mkdir($p, 0755, true);
     if (!file_exists($p)) {
     } while (file_exists($p));
     @mkdir($p, 0755, true);
     if (!file_exists($p)) {
-        echo 'Error';
-        return;
+        return 'Error: cannot create async folder.';
     }
 
     /* touch empty data file */
     }
 
     /* touch empty data file */
@@ -962,7 +989,7 @@ function jirafeau_async_init($filename, $type, $one_time, $key, $time, $ip)
         $password = md5($key);
     }
 
         $password = md5($key);
     }
 
-    /* Store informations. */
+    /* Store information. */
     $p .= $ref;
     $handle = fopen($p, 'w');
     fwrite(
     $p .= $ref;
     $handle = fopen($p, 'w');
     fwrite(
@@ -983,7 +1010,7 @@ function jirafeau_async_init($filename, $type, $one_time, $key, $time, $ip)
   * @param $file piece of data
   * @param $code client code for this operation
   * @param $max_file_size maximum allowed file size
   * @param $file piece of data
   * @param $code client code for this operation
   * @param $max_file_size maximum allowed file size
-  * @return a string containing a next code to use or the string "Error"
+  * @return a string containing a next code to use or a string starting with 'Error'
   */
 function jirafeau_async_push($ref, $data, $code, $max_file_size)
 {
   */
 function jirafeau_async_push($ref, $data, $code, $max_file_size)
 {
@@ -991,11 +1018,22 @@ function jirafeau_async_push($ref, $data, $code, $max_file_size)
     $a = jirafeau_get_async_ref($ref);
 
     /* Check some errors. */
     $a = jirafeau_get_async_ref($ref);
 
     /* Check some errors. */
-    if (count($a) == 0
-        || $a['next_code'] != "$code"
-        || empty($data['tmp_name'])
-        || !is_uploaded_file($data['tmp_name'])) {
-        return 'Error';
+    if (count($a) == 0) {
+        return "Error: cannot find transfer";
+    }
+    if ($a['next_code'] != "$code") {
+        return "Error: bad transfer code";
+    }
+    if ($data['error'] != UPLOAD_ERR_OK) {
+        // Check error code in https://www.php.net/manual/en/features.file-upload.errors.php
+        $data_details = print_r($data, true);
+        return "Error: upload error: {$data_details}";
+    }
+    if (empty($data['tmp_name'])) {
+        return "Error: missing tmp_name";
+    }
+    if (!is_uploaded_file($data['tmp_name'])) {
+        return "Error: tmp_name may not be uploaded";
     }
 
     $p = s2p($ref);
     }
 
     $p = s2p($ref);
@@ -1008,7 +1046,7 @@ function jirafeau_async_push($ref, $data, $code, $max_file_size)
     if ($max_file_size > 0 &&
         filesize($r_path) + filesize($w_path) > $max_file_size * 1024 * 1024) {
         jirafeau_async_delete($ref);
     if ($max_file_size > 0 &&
         filesize($r_path) + filesize($w_path) > $max_file_size * 1024 * 1024) {
         jirafeau_async_delete($ref);
-        return 'Error';
+        return "Error: file size is above upload limit";
     }
 
     /* Concatenate data. */
     }
 
     /* Concatenate data. */
@@ -1019,7 +1057,7 @@ function jirafeau_async_push($ref, $data, $code, $max_file_size)
             fclose($r);
             fclose($w);
             jirafeau_async_delete($ref);
             fclose($r);
             fclose($w);
             jirafeau_async_delete($ref);
-            return 'Error';
+            return "Error: cannot write file";
         }
     }
     fclose($r);
         }
     }
     fclose($r);
@@ -1040,12 +1078,12 @@ function jirafeau_async_push($ref, $data, $code, $max_file_size)
 }
 
 /**
 }
 
 /**
-  * Finalyze an asynchronous upload.
+  * Finalize an asynchronous upload.
   * @param $ref asynchronous upload reference
   * @param $code client code for this operation
   * @param $crypt boolean asking to crypt or not
   * @param $link_name_length link name length
   * @param $ref asynchronous upload reference
   * @param $code client code for this operation
   * @param $crypt boolean asking to crypt or not
   * @param $link_name_length link name length
-  * @return a string containing the download reference followed by a delete code or the string 'Error'
+  * @return a string containing the download reference followed by a delete code or a string starting with 'Error'
   */
 function jirafeau_async_end($ref, $code, $crypt, $link_name_length, $file_hash_method)
 {
   */
 function jirafeau_async_end($ref, $code, $crypt, $link_name_length, $file_hash_method)
 {
@@ -1053,13 +1091,13 @@ function jirafeau_async_end($ref, $code, $crypt, $link_name_length, $file_hash_m
     $a = jirafeau_get_async_ref($ref);
     if (count($a) == 0
         || $a['next_code'] != "$code") {
     $a = jirafeau_get_async_ref($ref);
     if (count($a) == 0
         || $a['next_code'] != "$code") {
-        return "Error";
+        return "Error: bad code for ending transfer";
     }
 
     /* Generate link infos. */
     $p = VAR_ASYNC . s2p($ref) . $ref . "_data";
     if (!file_exists($p)) {
     }
 
     /* Generate link infos. */
     $p = VAR_ASYNC . s2p($ref) . $ref . "_data";
     if (!file_exists($p)) {
-        return 'Error';
+        return "Error: referenced file does not exist";
     }
 
     $crypted = false;
     }
 
     $crypted = false;
@@ -1107,9 +1145,11 @@ function jirafeau_async_end($ref, $code, $crypt, $link_name_length, $file_hash_m
     fclose($handle);
     $hash_link = substr(base_16_to_64(md5_file($link_tmp_name)), 0, $link_name_length);
     $l = s2p("$hash_link");
     fclose($handle);
     $hash_link = substr(base_16_to_64(md5_file($link_tmp_name)), 0, $link_name_length);
     $l = s2p("$hash_link");
-    if (!@mkdir(VAR_LINKS . $l, 0755, true) ||
-        !rename($link_tmp_name, VAR_LINKS . $l . $hash_link)) {
-        return 'Error';
+    if (!@mkdir(VAR_LINKS . $l, 0755, true)) {
+        return "Error: cannot create folder in LINKS";
+    }
+    if (!rename($link_tmp_name, VAR_LINKS . $l . $hash_link)) {
+        return "Error: cannot rename file in LINKS";
     }
 
     /* Clean async upload. */
     }
 
     /* Clean async upload. */
@@ -1517,3 +1557,8 @@ function jirafeau_add_ending_slash($path)
 {
     return $path . ((substr($path, -1) == '/') ? '' : '/');
 }
 {
     return $path . ((substr($path, -1) == '/') ? '' : '/');
 }
+
+function jirafeau_default_web_root()
+{
+    return $_SERVER['HTTP_HOST'] . str_replace(basename(__FILE__), '', $_SERVER['REQUEST_URI']);
+}

patrick-canterino.de