Browse Source

FIX Add a better message when file size is too large

Laurent Destailleur 4 years ago
parent
commit
581a3d8808

+ 3 - 0
htdocs/core/class/html.formfile.class.php

@@ -114,6 +114,9 @@ class FormFile
 
 			if (empty($usewithoutform))		// Try to avoid this and set instead the form by the caller.
 			{
+				// Add a param as GET parameter to detect when POST were cleaned by PHP because a file larger than post_max_size
+				$url .= (strpos('?', $url) === false ? '?' : '&').'uploadform=1';
+
 				$out .= '<form name="'.$htmlname.'" id="'.$htmlname.'" action="'.$url.'" enctype="multipart/form-data" method="POST">';
 				$out .= '<input type="hidden" name="token" value="'.newToken().'">';
 				$out .= '<input type="hidden" id="'.$htmlname.'_section_dir" name="section_dir" value="'.$sectiondir.'">';

+ 42 - 0
htdocs/core/lib/functions.lib.php

@@ -8919,3 +8919,45 @@ function addSummaryTableLine($tableColumnCount, $num, $nbofloop = 0, $total = 0,
 
 	print '</tr>';
 }
+
+/**
+ *	Return a file on output using a lo memory.
+ *  It can return very large files with no need of memory.
+ *
+ *  @param	string	$fullpath_original_file_osencoded		Full path of file to return.
+ *  @param	int		$method									-1 automatic, 0=readfile, 1=fread, 2=stream_copy_to_stream
+ */
+function readfileLowMemory($fullpath_original_file_osencoded, $method = -1)
+{
+	global $conf;
+
+	if ($method == -1) {
+		$method = 0;
+		if (! empty($conf->global->MAIN_FORCE_READFILE_WITH_FREAD)) $method = 1;
+		if (! empty($conf->global->MAIN_FORCE_READFILE_WITH_STREAM_COPY)) $method = 2;
+	}
+
+	// Solution 0
+	if ($method == 0) {
+		// Be sure we don't have output buffering enabled to have readfile working correctly
+		while (ob_get_level()) ob_end_flush();
+
+		readfile($fullpath_original_file_osencoded);
+	}
+	// Solution 1
+	elseif ($method == 1) {
+		$handle = fopen($fullpath_original_file_osencoded, "rb");
+		while (!feof($handle)) {
+			print fread($handle, 8192);
+		}
+		fclose($handle);
+	}
+	// Solution 2
+	elseif ($method == 2) {
+		$handle1 = fopen($fullpath_original_file_osencoded, "rb");
+		$handle2 = fopen("php://output", "wb");
+		stream_copy_to_stream($handle1, $handle2);
+		fclose($handle1);
+		fclose($handle2);
+	}
+}

+ 4 - 3
htdocs/document.php

@@ -261,10 +261,11 @@ if (!$attachment && !empty($conf->global->MAIN_USE_EXIF_ROTATION) && image_forma
 	$readfile = !$imgres;
 }
 
+if (is_object($db)) $db->close();
+
+// Send file now
 if ($readfile) {
 	header('Content-Length: '.dol_filesize($fullpath_original_file));
 
-	readfile($fullpath_original_file_osencoded);
+	readfileLowMemory($fullpath_original_file_osencoded);
 }
-
-if (is_object($db)) $db->close();

+ 12 - 4
htdocs/main.inc.php

@@ -378,10 +378,18 @@ if ((!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && !empty($conf->gl
 		in_array(GETPOST('action', 'aZ09'), array('add', 'addtimespent', 'update', 'install', 'delete', 'deleteprof', 'deletepayment')))
 	{
 		if (!GETPOSTISSET('token')) {
-			dol_syslog("--- Access to ".$_SERVER["PHP_SELF"]." refused by CSRFCHECK_WITH_TOKEN protection. Token not provided.");
-			print "Access to this page this way (POST method or page with CSRFCHECK_WITH_TOKEN on or having a sensible value for action parameter) is refused by CSRF protection in main.inc.php. Token not provided.\n";
-			print "If you access your server behind a proxy using url rewriting, you might check that all HTTP header is propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file or MAIN_SECURITY_CSRF_WITH_TOKEN to 0 into setup).\n";
-			die;
+			if (GETPOST('uploadform')) {
+				dol_syslog("--- Access to ".$_SERVER["PHP_SELF"]." refused. File size too large.");
+				$langs->loadLangs(array("errors", "install"));
+				print $langs->trans("ErrorFileSizeTooLarge").' ';
+				print $langs->trans("ErrorGoBackAndCorrectParameters");
+				die;
+			} else {
+				dol_syslog("--- Access to ".$_SERVER["PHP_SELF"]." refused by CSRFCHECK_WITH_TOKEN protection. Token not provided.");
+				print "Access to this page this way (POST method or page with CSRFCHECK_WITH_TOKEN on or having a sensible value for action parameter) is refused by CSRF protection in main.inc.php. Token not provided.\n";
+				print "If you access your server behind a proxy using url rewriting, you might check that all HTTP header is propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file or MAIN_SECURITY_CSRF_WITH_TOKEN to 0 into setup).\n";
+				die;
+			}
 		}
 	}