diff --git a/src/Core/Exception/ValidatorException.php b/src/Core/Exception/ValidatorException.php index f3c97e2dc9..f789367805 100644 --- a/src/Core/Exception/ValidatorException.php +++ b/src/Core/Exception/ValidatorException.php @@ -18,7 +18,7 @@ class ValidatorException extends \InvalidArgumentException { private $errors; - public function __construct($message, array $errors, Exception $previous = null) + public function __construct($message, array $errors, \Exception $previous = null) { $flatErrors = iterator_to_array(new RecursiveIteratorIterator(new RecursiveArrayIterator($errors)), false); diff --git a/src/Core/Tool/Uploader.php b/src/Core/Tool/Uploader.php index 4d30a1899e..c2cf3963f1 100644 --- a/src/Core/Tool/Uploader.php +++ b/src/Core/Tool/Uploader.php @@ -44,9 +44,10 @@ public function upload(UploadData $file, $filename = null) $filename = uniqid() . '-' . $file->name; } - // Avoid any possible issues with case sensitivity by forcing all files - // to be made lowercase. - $filename = strtolower($filename); + // Avoid possible issues with case sensitivity by forcing all files + // to be made lowercase. Also replace possibly invalid characters in filename + $filename = strtolower(preg_replace('/[^\pL\pN\-\_\s\.]+/u', '', $filename)); + // Add the first and second letters of filename to the directory path // to help segment the files, producing a more reasonable amount of @@ -66,9 +67,24 @@ public function upload(UploadData $file, $filename = null) $extension = pathinfo($filepath, PATHINFO_EXTENSION); $mimeType = MimeType::detectByFileExtension($extension) ?: 'text/plain'; $config = ['mimetype' => $mimeType]; - $this->fs->putStream($filepath, $stream, $config); - if (is_resource($stream)) { - fclose($stream); + + try { + $this->fs->putStream($filepath, $stream, $config); + } catch (\Guzzle\Http\Exception\ClientErrorResponseException $e) { + // Flysystem and FlysystemRackspace are very leaky abstractions + // so we have to manually catch guzzle errors here + $response = $e->getResponse(); + + throw new \InvalidArgumentException('Could not upload file: '. $response->getBody(true)); + } catch (\Guzzle\Http\Exception\BadResponseException $e) { + // Flysystem and FlysystemRackspace are very leaky abstractions + // so we have to manually catch guzzle errors here + + throw new \InvalidArgumentException('Could not upload file'); + } finally { + if (is_resource($stream)) { + fclose($stream); + } } // Get meta information about the file. diff --git a/src/Core/Usecase/Media/CreateMedia.php b/src/Core/Usecase/Media/CreateMedia.php index 6bfd5fad9c..2a7d0ec232 100644 --- a/src/Core/Usecase/Media/CreateMedia.php +++ b/src/Core/Usecase/Media/CreateMedia.php @@ -15,7 +15,7 @@ use Ushahidi\Core\Tool\Uploader; use Ushahidi\Core\Tool\UploadData; use Ushahidi\Core\Usecase\CreateUsecase; -use Ushahidi\Exception\ValidatorException; +use Ushahidi\Core\Exception\ValidatorException; class CreateMedia extends CreateUsecase { @@ -62,7 +62,7 @@ public function interact() } catch (ValidatorException $e) { // If a file was uploaded, it must be purged after a failed upload. // Otherwise storage will be filled with junk files. - if ($this->fs->has($this->upload->file)) { + if ($this->upload && $this->fs->has($this->upload->file)) { $this->fs->delete($this->upload->file); } @@ -79,9 +79,15 @@ public function interact() protected function getEntity() { // Upload the file and get the file reference - $this->upload = $this->uploader->upload( - new UploadData($this->getPayload('file')) - ); + try { + $this->upload = $this->uploader->upload( + new UploadData($this->getPayload('file')) + ); + } catch (\InvalidArgumentException $e) { + throw new ValidatorException($e->getMessage(), [ + 'file' => $e->getMessage() + ], $e); + } $payload = [ 'caption' => $this->getPayload('caption', false) ?: null,