0011156: big files can't be uploaded
authorPhilipp Schüle <p.schuele@metaways.de>
Thu, 16 Jul 2015 12:09:39 +0000 (14:09 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Fri, 24 Jul 2015 09:20:49 +0000 (11:20 +0200)
* switch file size to double as 32bit systems can't cope with big
integer sizes (> 2 GB / 2147483647 bytes)

https://forge.tine20.org/view.php?id=11156

Change-Id: I2b3bb64887962395d0f38bd53c3747a45cef6eb8
Reviewed-on: http://gerrit.tine20.com/customers/2046
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/Tinebase/TempFileTest.php
tine20/Tinebase/Model/TempFile.php
tine20/Tinebase/TempFile.php

index c572151..2629c33 100644 (file)
@@ -16,7 +16,7 @@ require_once dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'TestHelper.php'
 /**
  * Test class for Tinebase_TempFileTest
  */
-class Tinebase_TempFileTest extends PHPUnit_Framework_TestCase
+class Tinebase_TempFileTest extends TestCase
 {
     /**
      * unit under test (UIT)
@@ -32,19 +32,8 @@ class Tinebase_TempFileTest extends PHPUnit_Framework_TestCase
      */
     protected function setUp()
     {
-        Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
         $this->_instance = Tinebase_TempFile::getInstance();
-    }
-    
-    /**
-     * Tears down the fixture
-     * This method is called after a test is executed.
-     *
-     * @access protected
-     */
-    protected function tearDown()
-    {
-        Tinebase_TransactionManager::getInstance()->rollBack();
+        parent::setUp();
     }
     
     /**
@@ -60,4 +49,24 @@ class Tinebase_TempFileTest extends PHPUnit_Framework_TestCase
         $tempFile = $this->_instance->createTempFile($path, $filename);
         $this->assertEquals("_tüt", $tempFile->name);
     }
+
+    /**
+     * @see 0011156: big files can't be uploaded
+     */
+    public function testCreateTempFileWithBigSize()
+    {
+        $size = (double) (3.8 * 1024.0 * 1024.0 * 1024.0);
+        $tempFile = new Tinebase_Model_TempFile(array(
+            'id'          => '123',
+            'session_id'  => 'abc',
+            'time'        => Tinebase_DateTime::now()->get(Tinebase_Record_Abstract::ISO8601LONG),
+            'path'        => '/tmp/tmpfile',
+            'name'        => 'tmpfile',
+            'type'        => 'unknown',
+            'error'       => 0,
+            'size'        => $size, // 3.8 GB
+        ));
+        $createdTempFile = $this->_instance->create($tempFile);
+        $this->assertEquals(4080218931, $createdTempFile->size);
+    }
 }
index 0600b9e..673a940 100644 (file)
@@ -48,7 +48,7 @@ class Tinebase_Model_TempFile extends Tinebase_Record_Abstract
         'name'       => array('allowEmpty' => false),
         'type'       => array('allowEmpty' => false),
         'error'      => array('presence' => 'required', 'allowEmpty' => TRUE, 'Int'),
-        'size'       => array('allowEmpty' => true, 'Int')
+        'size'       => array('allowEmpty' => true)
     );
     
     /**
index 317c91e..993924f 100644 (file)
@@ -128,7 +128,7 @@ class Tinebase_TempFile extends Tinebase_Backend_Sql_Abstract implements Tinebas
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->DEBUG(__METHOD__ . '::' . __LINE__ . " XMLHttpRequest style upload to path " . $path);
             
             $name =       base64_decode($_SERVER['HTTP_X_FILE_NAME']);
-            $size = (int) $_SERVER['HTTP_X_FILE_SIZE'];
+            $size =       (double) $_SERVER['HTTP_X_FILE_SIZE'];
             $type =       $_SERVER['HTTP_X_FILE_TYPE'];
             $error =      0;
             
@@ -147,7 +147,7 @@ class Tinebase_TempFile extends Tinebase_Backend_Sql_Abstract implements Tinebas
                 if (! $tempfileHandle) {
                     throw new Tinebase_Exception('Could not open tempfile while uploading! ');
                 }
-                $size = stream_copy_to_stream($input, $tempfileHandle);
+                $size = (double) stream_copy_to_stream($input, $tempfileHandle);
                 fclose($input);
                 fclose($tempfileHandle);
             }
@@ -159,7 +159,7 @@ class Tinebase_TempFile extends Tinebase_Backend_Sql_Abstract implements Tinebas
             $uploadedFile = $_FILES['file'];
             
             $name  = $uploadedFile['name'];
-            $size  = $uploadedFile['size'];
+            $size  = (double) $uploadedFile['size'];
             $type  = $uploadedFile['type'];
             $error = $uploadedFile['error'];
             
@@ -195,7 +195,7 @@ class Tinebase_TempFile extends Tinebase_Backend_Sql_Abstract implements Tinebas
      * @param string $_path
      * @param string $_name
      * @param string $_type
-     * @param integer $_size
+     * @param double $_size
      * @param integer $_error
      * @return Tinebase_Model_TempFile
      */
@@ -213,7 +213,7 @@ class Tinebase_TempFile extends Tinebase_Backend_Sql_Abstract implements Tinebas
            'name'        => $filename,
            'type'        => ! empty($_type)  ? $_type  : 'unknown',
            'error'       => ! empty($_error) ? $_error : 0,
-           'size'        => ! empty($_size)  ? $_size  : filesize($_path),
+           'size'        => ! empty($_size)  ? (double) $_size  : (double) filesize($_path),
         ));
         
         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__
@@ -235,6 +235,7 @@ class Tinebase_TempFile extends Tinebase_Backend_Sql_Abstract implements Tinebas
         $path = tempnam(Tinebase_Core::getTempDir(), 'tine_tempfile_');
         $name = preg_replace('/\.\d+\.chunk$/', '', $_tempFiles->getFirstRecord()->name);
         $type = $_tempFiles->getFirstRecord()->type;
+        $size = 0.0;
         
         $fJoin = fopen($path, 'w+b');
         foreach ($_tempFiles as $tempFile) {
@@ -244,13 +245,16 @@ class Tinebase_TempFile extends Tinebase_Backend_Sql_Abstract implements Tinebas
             }
             
             // NOTE: stream_copy_to_stream is about 15% slower
-            while (!feof($fChunk)) fwrite($fJoin, fread($fChunk, 2097152 /* 2 MB */));
+            while (!feof($fChunk)) {
+                $bytesWritten = fwrite($fJoin, fread($fChunk, 2097152 /* 2 MB */));
+                $size += (double) $bytesWritten;
+            }
             fclose($fChunk);
         }
         
         fclose($fJoin);
         
-        return $this->createTempFile($path, $name, $type);
+        return $this->createTempFile($path, $name, $type, $size);
     }
     
     /**