From ea8219e1d462362985b526260cd71230a5db2afb Mon Sep 17 00:00:00 2001 From: shadlaws Date: Sat, 19 Jan 2013 00:59:55 +0100 Subject: #1941, 1948 - Fix possible warnings in movie and graphics helpers, add functions to convert between seconds and hh:mm:ss.dd. Also add unit tests for new movie helper functions. --- modules/gallery/tests/Movie_Helper_Test.php | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 modules/gallery/tests/Movie_Helper_Test.php (limited to 'modules/gallery/tests/Movie_Helper_Test.php') diff --git a/modules/gallery/tests/Movie_Helper_Test.php b/modules/gallery/tests/Movie_Helper_Test.php new file mode 100644 index 00000000..78ac21a1 --- /dev/null +++ b/modules/gallery/tests/Movie_Helper_Test.php @@ -0,0 +1,49 @@ + 0.5, + "00:00:06.00" => 6, + "00:00:59.99" => 59.999, + "00:01:00.00" => 60.001, + "00:07:00.00" => 7 * 60, + "00:45:19.00" => 45 * 60 + 19, + "03:45:19.00" => 3 * 3600 + 45 * 60 + 19, + "126:45:19.00" => 126 * 3600 + 45 * 60 + 19); + foreach ($times as $hhmmssdd => $seconds) { + $this->assert_equal($hhmmssdd, movie::seconds_to_hhmmssdd($seconds)); + } + } + + public function hhmmssdd_to_seconds_test() { + $times = array("0:00:00.01" => 0.01, + "00:00:00.50" => 0.5, + "00:00:06.00" => 6, + "00:00:59.99" => 59.99, + "00:01:00.00" => 60.00, + "00:07:00.00" => 7 * 60, + "00:45:19.00" => 45 * 60 + 19, + "03:45:19.00" => 3 * 3600 + 45 * 60 + 19, + "126:45:19.00" => 126 * 3600 + 45 * 60 + 19); + foreach ($times as $hhmmssdd => $seconds) { + $this->assert_equal($seconds, movie::hhmmssdd_to_seconds($hhmmssdd)); + } + } +} -- cgit v1.2.3 From d45a73777935c86fc5131955831833d7465b5e9d Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Mon, 21 Jan 2013 01:22:01 -0500 Subject: Update copyright to 2013. Fixes #1953. --- application/Bootstrap.php | 2 +- application/config/config.php | 2 +- index.php | 2 +- installer/cli.php | 2 +- installer/index.php | 2 +- installer/installer.php | 2 +- installer/web.php | 2 +- modules/akismet/controllers/admin_akismet.php | 2 +- modules/akismet/helpers/akismet.php | 2 +- modules/akismet/helpers/akismet_event.php | 2 +- modules/akismet/helpers/akismet_installer.php | 2 +- modules/akismet/tests/Akismet_Helper_Test.php | 2 +- modules/comment/controllers/admin_comments.php | 2 +- modules/comment/controllers/admin_manage_comments.php | 2 +- modules/comment/controllers/comments.php | 2 +- modules/comment/helpers/comment.php | 2 +- modules/comment/helpers/comment_block.php | 2 +- modules/comment/helpers/comment_event.php | 2 +- modules/comment/helpers/comment_installer.php | 2 +- modules/comment/helpers/comment_rest.php | 2 +- modules/comment/helpers/comment_rss.php | 2 +- modules/comment/helpers/comment_theme.php | 2 +- modules/comment/helpers/comments_rest.php | 2 +- modules/comment/helpers/item_comments_rest.php | 2 +- modules/comment/models/comment.php | 2 +- modules/comment/tests/Comment_Event_Test.php | 2 +- modules/comment/tests/Comment_Helper_Test.php | 2 +- modules/comment/tests/Comment_Model_Test.php | 2 +- modules/digibug/config/digibug.php | 2 +- modules/digibug/controllers/admin_digibug.php | 2 +- modules/digibug/controllers/digibug.php | 2 +- modules/digibug/helpers/digibug_event.php | 2 +- modules/digibug/helpers/digibug_installer.php | 2 +- modules/digibug/helpers/digibug_theme.php | 2 +- modules/digibug/models/digibug_proxy.php | 2 +- modules/digibug/tests/Digibug_Controller_Test.php | 2 +- modules/exif/controllers/exif.php | 2 +- modules/exif/helpers/exif.php | 2 +- modules/exif/helpers/exif_event.php | 2 +- modules/exif/helpers/exif_installer.php | 2 +- modules/exif/helpers/exif_task.php | 2 +- modules/exif/helpers/exif_theme.php | 2 +- modules/exif/models/exif_key.php | 2 +- modules/exif/models/exif_record.php | 2 +- modules/exif/tests/Exif_Test.php | 2 +- modules/g2_import/controllers/admin_g2_import.php | 2 +- modules/g2_import/controllers/g2.php | 2 +- modules/g2_import/helpers/g2_import.php | 2 +- modules/g2_import/helpers/g2_import_event.php | 2 +- modules/g2_import/helpers/g2_import_installer.php | 2 +- modules/g2_import/helpers/g2_import_task.php | 2 +- modules/g2_import/libraries/G2_Import_Exception.php | 2 +- modules/g2_import/models/g2_map.php | 2 +- modules/gallery/config/cache.php | 2 +- modules/gallery/config/cookie.php | 2 +- modules/gallery/config/database.php | 2 +- modules/gallery/config/locale.php | 2 +- modules/gallery/config/log_file.php | 2 +- modules/gallery/config/routes.php | 2 +- modules/gallery/config/session.php | 2 +- modules/gallery/config/upload.php | 2 +- modules/gallery/config/user_agents.php | 2 +- modules/gallery/controllers/admin.php | 2 +- modules/gallery/controllers/admin_advanced_settings.php | 2 +- modules/gallery/controllers/admin_dashboard.php | 2 +- modules/gallery/controllers/admin_graphics.php | 2 +- modules/gallery/controllers/admin_languages.php | 2 +- modules/gallery/controllers/admin_maintenance.php | 2 +- modules/gallery/controllers/admin_modules.php | 2 +- modules/gallery/controllers/admin_sidebar.php | 2 +- modules/gallery/controllers/admin_theme_options.php | 2 +- modules/gallery/controllers/admin_themes.php | 2 +- modules/gallery/controllers/admin_upgrade_checker.php | 2 +- modules/gallery/controllers/albums.php | 2 +- modules/gallery/controllers/combined.php | 2 +- modules/gallery/controllers/file_proxy.php | 2 +- modules/gallery/controllers/items.php | 2 +- modules/gallery/controllers/l10n_client.php | 2 +- modules/gallery/controllers/login.php | 2 +- modules/gallery/controllers/logout.php | 2 +- modules/gallery/controllers/movies.php | 2 +- modules/gallery/controllers/packager.php | 2 +- modules/gallery/controllers/permissions.php | 2 +- modules/gallery/controllers/photos.php | 2 +- modules/gallery/controllers/quick.php | 2 +- modules/gallery/controllers/reauthenticate.php | 2 +- modules/gallery/controllers/upgrader.php | 2 +- modules/gallery/controllers/uploader.php | 2 +- modules/gallery/controllers/user_profile.php | 2 +- modules/gallery/controllers/welcome_message.php | 2 +- modules/gallery/helpers/MY_html.php | 2 +- modules/gallery/helpers/MY_num.php | 2 +- modules/gallery/helpers/MY_remote.php | 2 +- modules/gallery/helpers/MY_url.php | 2 +- modules/gallery/helpers/MY_valid.php | 2 +- modules/gallery/helpers/access.php | 2 +- modules/gallery/helpers/ajax.php | 2 +- modules/gallery/helpers/album.php | 2 +- modules/gallery/helpers/auth.php | 2 +- modules/gallery/helpers/batch.php | 2 +- modules/gallery/helpers/block_manager.php | 2 +- modules/gallery/helpers/data_rest.php | 2 +- modules/gallery/helpers/dir.php | 2 +- modules/gallery/helpers/encoding.php | 2 +- modules/gallery/helpers/gallery.php | 2 +- modules/gallery/helpers/gallery_block.php | 2 +- modules/gallery/helpers/gallery_error.php | 2 +- modules/gallery/helpers/gallery_event.php | 2 +- modules/gallery/helpers/gallery_graphics.php | 2 +- modules/gallery/helpers/gallery_installer.php | 2 +- modules/gallery/helpers/gallery_rss.php | 2 +- modules/gallery/helpers/gallery_task.php | 2 +- modules/gallery/helpers/gallery_theme.php | 2 +- modules/gallery/helpers/graphics.php | 2 +- modules/gallery/helpers/identity.php | 2 +- modules/gallery/helpers/item.php | 2 +- modules/gallery/helpers/item_rest.php | 2 +- modules/gallery/helpers/items_rest.php | 2 +- modules/gallery/helpers/json.php | 2 +- modules/gallery/helpers/l10n_client.php | 2 +- modules/gallery/helpers/l10n_scanner.php | 2 +- modules/gallery/helpers/legal_file.php | 2 +- modules/gallery/helpers/locales.php | 2 +- modules/gallery/helpers/log.php | 2 +- modules/gallery/helpers/message.php | 2 +- modules/gallery/helpers/model_cache.php | 2 +- modules/gallery/helpers/module.php | 2 +- modules/gallery/helpers/movie.php | 2 +- modules/gallery/helpers/photo.php | 2 +- modules/gallery/helpers/random.php | 2 +- modules/gallery/helpers/site_status.php | 2 +- modules/gallery/helpers/system.php | 2 +- modules/gallery/helpers/task.php | 2 +- modules/gallery/helpers/theme.php | 2 +- modules/gallery/helpers/tree_rest.php | 2 +- modules/gallery/helpers/upgrade_checker.php | 2 +- modules/gallery/helpers/user_profile.php | 2 +- modules/gallery/helpers/xml.php | 2 +- modules/gallery/hooks/init_gallery.php | 2 +- modules/gallery/libraries/Admin_View.php | 2 +- modules/gallery/libraries/Block.php | 2 +- modules/gallery/libraries/Breadcrumb.php | 2 +- modules/gallery/libraries/Form_Script.php | 2 +- modules/gallery/libraries/Form_Uploadify.php | 2 +- modules/gallery/libraries/Form_Uploadify_buttons.php | 2 +- modules/gallery/libraries/Gallery_I18n.php | 2 +- modules/gallery/libraries/Gallery_View.php | 2 +- modules/gallery/libraries/IdentityProvider.php | 2 +- modules/gallery/libraries/InPlaceEdit.php | 2 +- modules/gallery/libraries/MY_Database.php | 2 +- modules/gallery/libraries/MY_Forge.php | 2 +- modules/gallery/libraries/MY_Input.php | 2 +- modules/gallery/libraries/MY_Kohana_Exception.php | 2 +- modules/gallery/libraries/MY_ORM.php | 2 +- modules/gallery/libraries/MY_View.php | 2 +- modules/gallery/libraries/Menu.php | 2 +- modules/gallery/libraries/ORM_MPTT.php | 2 +- modules/gallery/libraries/SafeString.php | 2 +- modules/gallery/libraries/Sendmail.php | 2 +- modules/gallery/libraries/Task_Definition.php | 2 +- modules/gallery/libraries/Theme_View.php | 2 +- modules/gallery/libraries/drivers/Cache/Database.php | 2 +- modules/gallery/libraries/drivers/IdentityProvider.php | 2 +- modules/gallery/models/access_cache.php | 2 +- modules/gallery/models/access_intent.php | 2 +- modules/gallery/models/cache.php | 2 +- modules/gallery/models/failed_auth.php | 2 +- modules/gallery/models/graphics_rule.php | 2 +- modules/gallery/models/incoming_translation.php | 2 +- modules/gallery/models/item.php | 2 +- modules/gallery/models/log.php | 2 +- modules/gallery/models/message.php | 2 +- modules/gallery/models/module.php | 2 +- modules/gallery/models/outgoing_translation.php | 2 +- modules/gallery/models/permission.php | 2 +- modules/gallery/models/task.php | 2 +- modules/gallery/models/theme.php | 2 +- modules/gallery/models/var.php | 2 +- modules/gallery/tests/Access_Helper_Test.php | 2 +- modules/gallery/tests/Albums_Controller_Test.php | 2 +- modules/gallery/tests/Breadcrumb_Test.php | 2 +- modules/gallery/tests/Cache_Test.php | 2 +- modules/gallery/tests/Controller_Auth_Test.php | 2 +- modules/gallery/tests/Data_Rest_Helper_Test.php | 2 +- modules/gallery/tests/Database_Test.php | 2 +- modules/gallery/tests/Dir_Helper_Test.php | 2 +- modules/gallery/tests/DrawForm_Test.php | 2 +- modules/gallery/tests/File_Proxy_Controller_Test.php | 2 +- modules/gallery/tests/File_Structure_Test.php | 4 ++-- modules/gallery/tests/Gallery_Filters.php | 2 +- modules/gallery/tests/Gallery_I18n_Test.php | 2 +- modules/gallery/tests/Gallery_Installer_Test.php | 2 +- modules/gallery/tests/Html_Helper_Test.php | 2 +- modules/gallery/tests/Input_Library_Test.php | 2 +- modules/gallery/tests/Item_Helper_Test.php | 2 +- modules/gallery/tests/Item_Model_Test.php | 2 +- modules/gallery/tests/Item_Rest_Helper_Test.php | 2 +- modules/gallery/tests/Items_Rest_Helper_Test.php | 2 +- modules/gallery/tests/Kohana_Exception_Test.php | 2 +- modules/gallery/tests/Legal_File_Helper_Test.php | 2 +- modules/gallery/tests/Locales_Helper_Test.php | 2 +- modules/gallery/tests/Menu_Test.php | 2 +- modules/gallery/tests/Movie_Helper_Test.php | 2 +- modules/gallery/tests/Num_Helper_Test.php | 2 +- modules/gallery/tests/ORM_MPTT_Test.php | 2 +- modules/gallery/tests/Photos_Controller_Test.php | 2 +- modules/gallery/tests/SafeString_Test.php | 2 +- modules/gallery/tests/Sendmail_Test.php | 2 +- modules/gallery/tests/System_Helper_Test.php | 2 +- modules/gallery/tests/Url_Security_Test.php | 2 +- modules/gallery/tests/Valid_Test.php | 2 +- modules/gallery/tests/Var_Test.php | 2 +- modules/gallery/tests/Xss_Security_Test.php | 2 +- modules/gallery_unit_test/controllers/gallery_unit_test.php | 2 +- modules/gallery_unit_test/helpers/MY_request.php | 2 +- modules/gallery_unit_test/helpers/test.php | 2 +- modules/gallery_unit_test/libraries/Gallery_Unit_Test_Case.php | 2 +- modules/image_block/controllers/image_block.php | 2 +- modules/image_block/helpers/image_block_block.php | 2 +- modules/image_block/helpers/image_block_installer.php | 2 +- modules/info/helpers/info_block.php | 2 +- modules/info/helpers/info_installer.php | 2 +- modules/info/helpers/info_theme.php | 2 +- modules/kohana23_compat/config/pagination.php | 2 +- modules/kohana23_compat/libraries/MY_Database_Builder.php | 2 +- modules/kohana23_compat/libraries/Pagination.php | 2 +- modules/notification/controllers/notification.php | 2 +- modules/notification/helpers/notification.php | 2 +- modules/notification/helpers/notification_event.php | 2 +- modules/notification/helpers/notification_installer.php | 2 +- modules/notification/models/pending_notification.php | 2 +- modules/notification/models/subscription.php | 2 +- modules/organize/controllers/organize.php | 2 +- modules/organize/helpers/organize_event.php | 2 +- modules/organize/helpers/organize_installer.php | 2 +- modules/recaptcha/controllers/admin_recaptcha.php | 2 +- modules/recaptcha/helpers/recaptcha.php | 2 +- modules/recaptcha/helpers/recaptcha_event.php | 2 +- modules/recaptcha/helpers/recaptcha_installer.php | 2 +- modules/recaptcha/helpers/recaptcha_theme.php | 2 +- modules/recaptcha/libraries/Form_Recaptcha.php | 2 +- modules/rest/controllers/rest.php | 2 +- modules/rest/helpers/registry_rest.php | 2 +- modules/rest/helpers/rest.php | 2 +- modules/rest/helpers/rest_event.php | 2 +- modules/rest/helpers/rest_installer.php | 2 +- modules/rest/libraries/Rest_Exception.php | 2 +- modules/rest/models/user_access_key.php | 2 +- modules/rest/tests/Rest_Controller_Test.php | 2 +- modules/rss/controllers/rss.php | 2 +- modules/rss/helpers/rss.php | 2 +- modules/rss/helpers/rss_block.php | 2 +- modules/search/controllers/search.php | 2 +- modules/search/helpers/search.php | 2 +- modules/search/helpers/search_event.php | 2 +- modules/search/helpers/search_installer.php | 2 +- modules/search/helpers/search_task.php | 2 +- modules/search/helpers/search_theme.php | 2 +- modules/search/models/search_record.php | 2 +- modules/server_add/controllers/admin_server_add.php | 2 +- modules/server_add/controllers/server_add.php | 2 +- modules/server_add/helpers/server_add.php | 2 +- modules/server_add/helpers/server_add_event.php | 2 +- modules/server_add/helpers/server_add_installer.php | 2 +- modules/server_add/helpers/server_add_theme.php | 2 +- modules/server_add/models/server_add_entry.php | 2 +- modules/slideshow/helpers/slideshow_event.php | 2 +- modules/slideshow/helpers/slideshow_installer.php | 2 +- modules/slideshow/helpers/slideshow_theme.php | 2 +- modules/tag/controllers/admin_tags.php | 2 +- modules/tag/controllers/tag.php | 2 +- modules/tag/controllers/tag_name.php | 2 +- modules/tag/controllers/tags.php | 2 +- modules/tag/helpers/item_tags_rest.php | 2 +- modules/tag/helpers/tag.php | 2 +- modules/tag/helpers/tag_block.php | 2 +- modules/tag/helpers/tag_event.php | 2 +- modules/tag/helpers/tag_installer.php | 2 +- modules/tag/helpers/tag_item_rest.php | 2 +- modules/tag/helpers/tag_items_rest.php | 2 +- modules/tag/helpers/tag_rest.php | 2 +- modules/tag/helpers/tag_rss.php | 2 +- modules/tag/helpers/tag_task.php | 2 +- modules/tag/helpers/tag_theme.php | 2 +- modules/tag/helpers/tags_rest.php | 2 +- modules/tag/models/tag.php | 2 +- modules/tag/tests/Tag_Item_Rest_Helper_Test.php | 2 +- modules/tag/tests/Tag_Rest_Helper_Test.php | 2 +- modules/tag/tests/Tag_Test.php | 2 +- modules/tag/tests/Tags_Rest_Helper_Test.php | 2 +- modules/user/config/identity.php | 2 +- modules/user/controllers/admin_users.php | 2 +- modules/user/controllers/password.php | 2 +- modules/user/controllers/users.php | 2 +- modules/user/helpers/group.php | 2 +- modules/user/helpers/user.php | 2 +- modules/user/helpers/user_event.php | 2 +- modules/user/helpers/user_installer.php | 2 +- modules/user/helpers/user_theme.php | 2 +- modules/user/libraries/drivers/IdentityProvider/Gallery.php | 2 +- modules/user/models/group.php | 2 +- modules/user/models/user.php | 2 +- modules/user/tests/No_Direct_ORM_Access_Test.php | 2 +- modules/user/tests/User_Groups_Test.php | 2 +- modules/user/tests/User_Installer_Test.php | 2 +- modules/watermark/controllers/admin_watermarks.php | 2 +- modules/watermark/helpers/watermark.php | 2 +- modules/watermark/helpers/watermark_event.php | 2 +- modules/watermark/helpers/watermark_installer.php | 2 +- 309 files changed, 310 insertions(+), 310 deletions(-) (limited to 'modules/gallery/tests/Movie_Helper_Test.php') diff --git a/application/Bootstrap.php b/application/Bootstrap.php index 183705d9..93353b47 100644 --- a/application/Bootstrap.php +++ b/application/Bootstrap.php @@ -1,7 +1,7 @@ Date: Sat, 26 Jan 2013 00:04:55 +0100 Subject: #1951 - Make metadata generation more flexible (photo and movie helpers). - added photo_get_file_metadata and movie_get_file_metadata events - modified photo::get_file_metadata and movie::get_file_metadata to use them - ensure that non-readable files throw exceptions - redirected other photo metadata calls in core to photo::get_file_metadata (the helper function already exists, but in many places getimagesize is still called directly) - added some unit tests (neither of the functions above had one) --- modules/gallery/helpers/graphics.php | 10 +-- modules/gallery/helpers/movie.php | 86 ++++++++++++++++------ modules/gallery/helpers/photo.php | 63 +++++++++++++--- modules/gallery/tests/Movie_Helper_Test.php | 32 ++++++++ modules/gallery/tests/Photo_Helper_Test.php | 56 ++++++++++++++ modules/watermark/controllers/admin_watermarks.php | 32 +++----- 6 files changed, 218 insertions(+), 61 deletions(-) create mode 100644 modules/gallery/tests/Photo_Helper_Test.php (limited to 'modules/gallery/tests/Movie_Helper_Test.php') diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php index 51437d4b..0c5f8366 100644 --- a/modules/gallery/helpers/graphics.php +++ b/modules/gallery/helpers/graphics.php @@ -195,9 +195,8 @@ class graphics_Core { } else { copy(MODPATH . "gallery/images/missing_photo.png", $item->thumb_path()); } - $dims = getimagesize($item->thumb_path()); - $item->thumb_width = $dims[0]; - $item->thumb_height = $dims[1]; + list ($item->thumb_width, $item->thumb_height) = + photo::get_file_metadata($item->thumb_path()); } if (!empty($ops["resize"])) { @@ -206,9 +205,8 @@ class graphics_Core { } else { copy(MODPATH . "gallery/images/missing_photo.png", $item->resize_path()); } - $dims = getimagesize($item->resize_path()); - $item->resize_width = $dims[0]; - $item->resize_height = $dims[1]; + list ($item->resize_width, $item->resize_height) = + photo::get_file_metadata($item->resize_path()); } $item->save(); } catch (Exception $e) { diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php index 7e6a2e55..6844771b 100644 --- a/modules/gallery/helpers/movie.php +++ b/modules/gallery/helpers/movie.php @@ -123,41 +123,79 @@ class movie_Core { /** * Return the width, height, mime_type, extension and duration of the given movie file. + * Metadata is first generated using ffmpeg (or set to defaults if it fails), + * then can be modified by other modules using movie_get_file_metadata events. + * + * This function and its use cases are symmetric to those of photo::get_file_metadata. + * + * @param string $file_path + * @return array array($width, $height, $mime_type, $extension, $duration) + * + * Use cases in detail: + * Input is standard movie type (flv/mp4/m4v) + * -> return metadata from ffmpeg + * Input is *not* standard movie type that is supported by ffmpeg (e.g. avi, mts...) + * -> return metadata from ffmpeg + * Input is *not* standard movie type that is *not* supported by ffmpeg but is legal + * -> return zero width, height, and duration; mime type and extension according to legal_file + * Input is *not* standard movie type that is *not* supported by ffmpeg and is *not* legal + * -> return zero width, height, and duration; null mime type and extension + * Input is not readable or does not exist + * -> throw exception + * Note: movie_get_file_metadata events can change any of the above cases (except the last one). */ static function get_file_metadata($file_path) { - $ffmpeg = movie::find_ffmpeg(); - if (empty($ffmpeg)) { - throw new Exception("@todo MISSING_FFMPEG"); + if (!is_readable($file_path)) { + throw new Exception("@todo UNREADABLE_FILE"); } - $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($file_path) . " 2>&1"; - $result = `$cmd`; - if (preg_match("/Stream.*?Video:.*?, (\d+)x(\d+)/", $result, $matches_res)) { - if (preg_match("/Stream.*?Video:.*? \[.*?DAR (\d+):(\d+).*?\]/", $result, $matches_dar) && - $matches_dar[1] >= 1 && $matches_dar[2] >= 1) { - // DAR is defined - determine width based on height and DAR - // (should always be int, but adding round to be sure) - $matches_res[1] = round($matches_res[2] * $matches_dar[1] / $matches_dar[2]); + $metadata = new stdClass(); + $ffmpeg = movie::find_ffmpeg(); + if (!empty($ffmpeg)) { + // ffmpeg found - use it to get width, height, and duration. + $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($file_path) . " 2>&1"; + $result = `$cmd`; + if (preg_match("/Stream.*?Video:.*?, (\d+)x(\d+)/", $result, $matches_res)) { + if (preg_match("/Stream.*?Video:.*? \[.*?DAR (\d+):(\d+).*?\]/", $result, $matches_dar) && + $matches_dar[1] >= 1 && $matches_dar[2] >= 1) { + // DAR is defined - determine width based on height and DAR + // (should always be int, but adding round to be sure) + $matches_res[1] = round($matches_res[2] * $matches_dar[1] / $matches_dar[2]); + } + list ($metadata->width, $metadata->height) = array($matches_res[1], $matches_res[2]); + } else { + list ($metadata->width, $metadata->height) = array(0, 0); + } + + if (preg_match("/Duration: (\d+:\d+:\d+\.\d+)/", $result, $matches)) { + $metadata->duration = movie::hhmmssdd_to_seconds($matches[1]); + } else if (preg_match("/duration.*?:.*?(\d+)/", $result, $matches)) { + $metadata->duration = $matches[1]; + } else { + $metadata->duration = 0; } - list ($width, $height) = array($matches_res[1], $matches_res[2]); } else { - list ($width, $height) = array(0, 0); + // ffmpeg not found - set width, height, and duration to zero. + $metadata->width = 0; + $metadata->height = 0; + $metadata->duration = 0; } - $extension = strtolower(pathinfo($file_path, PATHINFO_EXTENSION)); - $extension = $extension ? $extension : "flv"; // No extension? Assume FLV. - $mime_type = legal_file::get_movie_types_by_extension($extension); - $mime_type = $mime_type ? $mime_type : "video/x-flv"; // No MIME found? Default to video/x-flv. - - if (preg_match("/Duration: (\d+:\d+:\d+\.\d+)/", $result, $matches)) { - $duration = movie::hhmmssdd_to_seconds($matches[1]); - } else if (preg_match("/duration.*?:.*?(\d+)/", $result, $matches)) { - $duration = $matches[1]; + $extension = pathinfo($file_path, PATHINFO_EXTENSION); + if (!$extension || + (!$metadata->mime_type = legal_file::get_movie_types_by_extension($extension))) { + // Extension is empty or illegal. + $metadata->extension = null; + $metadata->mime_type = null; } else { - $duration = 0; + // Extension is legal (and mime is already set above). + $metadata->extension = strtolower($extension); } - return array($width, $height, $mime_type, $extension, $duration); + // Run movie_get_file_metadata events which can modify the class, then return results. + module::event("movie_get_file_metadata", $file_path, $metadata); + return array($metadata->width, $metadata->height, $metadata->mime_type, + $metadata->extension, $metadata->duration); } /** diff --git a/modules/gallery/helpers/photo.php b/modules/gallery/helpers/photo.php index 855cd0ae..51e51507 100644 --- a/modules/gallery/helpers/photo.php +++ b/modules/gallery/helpers/photo.php @@ -80,20 +80,61 @@ class photo_Core { /** * Return the width, height, mime_type and extension of the given image file. + * Metadata is first generated using getimagesize (or the legal_file mapping if it fails), + * then can be modified by other modules using photo_get_file_metadata events. + * + * This function and its use cases are symmetric to those of photo::get_file_metadata. + * + * @param string $file_path + * @return array array($width, $height, $mime_type, $extension) + * + * Use cases in detail: + * Input is standard photo type (jpg/png/gif) + * -> return metadata from getimagesize() + * Input is *not* standard photo type that is supported by getimagesize (e.g. tif, bmp...) + * -> return metadata from getimagesize() + * Input is *not* standard photo type that is *not* supported by getimagesize but is legal + * -> return zero width and height, mime type and extension according to legal_file + * Input is *not* standard photo type that is *not* supported by getimagesize and is *not* legal + * -> return zero width and height, null mime type and extension + * Input is not readable or does not exist + * -> throw exception + * Note: photo_get_file_metadata events can change any of the above cases (except the last one). */ static function get_file_metadata($file_path) { - $image_info = getimagesize($file_path); - if ($image_info) { - $width = $image_info[0]; - $height = $image_info[1]; - $mime_type = $image_info["mime"]; - $extension = image_type_to_extension($image_info[2], false); - return array($width, $height, $mime_type, $extension); + if (!is_readable($file_path)) { + throw new Exception("@todo UNREADABLE_FILE"); + } + + $metadata = new stdClass(); + if ($image_info = getimagesize($file_path)) { + // getimagesize worked - use its results. + $metadata->width = $image_info[0]; + $metadata->height = $image_info[1]; + $metadata->mime_type = $image_info["mime"]; + $metadata->extension = image_type_to_extension($image_info[2], false); + // We prefer jpg instead of jpeg (which is returned by image_type_to_extension). + if ($metadata->extension == "jpeg") { + $metadata->extension = "jpg"; + } } else { - // getimagesize failed - use legal_file mapping instead. - $extension = strtolower(pathinfo($file_path, PATHINFO_EXTENSION)); - $mime_type = legal_file::get_photo_types_by_extension($extension); - return array(0, 0, $mime_type, $extension); + // getimagesize failed - try to use legal_file mapping instead. + $extension = pathinfo($file_path, PATHINFO_EXTENSION); + if (!$extension || + (!$metadata->mime_type = legal_file::get_photo_types_by_extension($extension))) { + // Extension is empty or illegal. + $metadata->extension = null; + $metadata->mime_type = null; + } else { + // Extension is legal (and mime is already set above). + $metadata->extension = strtolower($extension); + } + $metadata->width = 0; + $metadata->height = 0; } + + // Run photo_get_file_metadata events which can modify the class, then return results. + module::event("photo_get_file_metadata", $file_path, $metadata); + return array($metadata->width, $metadata->height, $metadata->mime_type, $metadata->extension); } } diff --git a/modules/gallery/tests/Movie_Helper_Test.php b/modules/gallery/tests/Movie_Helper_Test.php index ff7f798c..0c262620 100644 --- a/modules/gallery/tests/Movie_Helper_Test.php +++ b/modules/gallery/tests/Movie_Helper_Test.php @@ -46,4 +46,36 @@ class Movie_Helper_Test extends Gallery_Unit_Test_Case { $this->assert_equal($seconds, movie::hhmmssdd_to_seconds($hhmmssdd)); } } + + public function get_file_metadata_test() { + $movie = test::random_movie(); + $this->assert_equal(array(360, 288, "video/x-flv", "flv", 6.00), + movie::get_file_metadata($movie->file_path())); + } + + public function get_file_metadata_with_non_existent_file_test() { + try { + $metadata = movie::get_file_metadata(MODPATH . "gallery/tests/this_does_not_exist"); + $this->assert_true(false, "Shouldn't get here"); + } catch (Exception $e) { + // pass + } + } + + public function get_file_metadata_with_no_extension_test() { + copy(MODPATH . "gallery/tests/test.flv", TMPPATH . "test_flv_with_no_extension"); + $this->assert_equal(array(360, 288, null, null, 6.00), + movie::get_file_metadata(TMPPATH . "test_flv_with_no_extension")); + } + + public function get_file_metadata_with_illegal_extension_test() { + $this->assert_equal(array(0, 0, null, null, 0), + movie::get_file_metadata(MODPATH . "gallery/tests/Movie_Helper_Test.php")); + } + + public function get_file_metadata_with_illegal_extension_but_valid_file_contents_test() { + copy(MODPATH . "gallery/tests/test.flv", TMPPATH . "test_flv_with_php_extension.php"); + $this->assert_equal(array(360, 288, null, null, 6.00), + movie::get_file_metadata(TMPPATH . "test_flv_with_php_extension.php")); + } } diff --git a/modules/gallery/tests/Photo_Helper_Test.php b/modules/gallery/tests/Photo_Helper_Test.php new file mode 100644 index 00000000..5207a6db --- /dev/null +++ b/modules/gallery/tests/Photo_Helper_Test.php @@ -0,0 +1,56 @@ +assert_equal(array(1024, 768, "image/jpeg", "jpg"), + photo::get_file_metadata($photo->file_path())); + } + + public function get_file_metadata_with_non_existent_file_test() { + try { + $metadata = photo::get_file_metadata(MODPATH . "gallery/tests/this_does_not_exist"); + $this->assert_true(false, "Shouldn't get here"); + } catch (Exception $e) { + // pass + } + } + + public function get_file_metadata_with_no_extension_test() { + copy(MODPATH . "gallery/tests/test.jpg", TMPPATH . "test_jpg_with_no_extension"); + $this->assert_equal(array(1024, 768, "image/jpeg", "jpg"), + photo::get_file_metadata(TMPPATH . "test_jpg_with_no_extension")); + } + + public function get_file_metadata_with_illegal_extension_test() { + $this->assert_equal(array(0, 0, null, null), + photo::get_file_metadata(MODPATH . "gallery/tests/Photo_Helper_Test.php")); + } + + public function get_file_metadata_with_illegal_extension_but_valid_file_contents_test() { + // This ensures that we correctly "re-type" files with invalid extensions if the contents + // themselves are valid. This is needed to ensure that issues similar to those corrected by + // ticket #1855, where an image that looked valid (header said jpg) with a php extension was + // previously accepted without changing its extension, do not arise and cause security issues. + copy(MODPATH . "gallery/tests/test.jpg", TMPPATH . "test_jpg_with_php_extension.php"); + $this->assert_equal(array(1024, 768, "image/jpeg", "jpg"), + photo::get_file_metadata(TMPPATH . "test_jpg_with_php_extension.php")); + } +} diff --git a/modules/watermark/controllers/admin_watermarks.php b/modules/watermark/controllers/admin_watermarks.php index 0e6e214b..14c2b394 100644 --- a/modules/watermark/controllers/admin_watermarks.php +++ b/modules/watermark/controllers/admin_watermarks.php @@ -100,32 +100,24 @@ class Admin_Watermarks_Controller extends Admin_Controller { $name = preg_replace("/uploadfile-[^-]+-(.*)/", '$1', $pathinfo["basename"]); $name = legal_file::smash_extensions($name); - if (!($image_info = getimagesize($file)) || - !in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) { - message::error(t("Unable to identify this image file")); + list ($width, $height, $mime_type, $extension) = photo::get_file_metadata($file); + if (!legal_file::get_photo_extensions($extension)) { + message::error(t("Invalid or unidentifiable image file")); @unlink($file); return; - } - - if (!in_array($pathinfo["extension"], legal_file::get_photo_extensions())) { - switch ($image_info[2]) { - case IMAGETYPE_GIF: - $name = legal_file::change_extension($name, "gif"); - break; - case IMAGETYPE_JPEG: - $name = legal_file::change_extension($name, "jpg"); - break; - case IMAGETYPE_PNG: - $name = legal_file::change_extension($name, "png"); - break; - } + } else { + // Force correct, legal extension type on file, which will be of our canonical type + // (i.e. all lowercase, jpg instead of jpeg, etc.). This renaming prevents the issues + // addressed in ticket #1855, where an image that looked valid (header said jpg) with a + // php extension was previously accepted without changing its extension. + $name = legal_file::change_extension($name, $extension); } rename($file, VARPATH . "modules/watermark/$name"); module::set_var("watermark", "name", $name); - module::set_var("watermark", "width", $image_info[0]); - module::set_var("watermark", "height", $image_info[1]); - module::set_var("watermark", "mime_type", $image_info["mime"]); + module::set_var("watermark", "width", $width); + module::set_var("watermark", "height", $height); + module::set_var("watermark", "mime_type", $mime_type); module::set_var("watermark", "position", $form->add_watermark->position->value); module::set_var("watermark", "transparency", $form->add_watermark->transparency->value); $this->_update_graphics_rules(); -- cgit v1.2.3 From 0312d1b071bd4434ddb3f82888b0323da6bf3732 Mon Sep 17 00:00:00 2001 From: shadlaws Date: Fri, 8 Feb 2013 13:51:41 +0100 Subject: #1994 - Make get_file_metadata throw an exception if photo or movie is unidentifiable/illegal. - photo & movie helpers: modified to throw exceptions when file is known to be unidentifiable/illegal. - item model: revised to work with exceptions and be more explicit when the data file is invalid. - item model: removed duplicate get_file_metadata call for updated items. - admin_watermarks controller: revised to work with exceptions (really cleans up logic here). - graphics helper: revised to handle invalid placeholders (a nearly-impossible corner case, but still...). - photo & movie helper tests: revised to work with exceptions, added new tests for illegal files with valid extensions. - item model tests: revised to work with exceptions, added new tests for illegal files with valid extensions. --- modules/gallery/helpers/gallery_graphics.php | 5 ++ modules/gallery/helpers/graphics.php | 11 +++- modules/gallery/helpers/movie.php | 10 ++- modules/gallery/helpers/photo.php | 9 ++- modules/gallery/models/item.php | 71 +++++++++++++--------- modules/gallery/tests/Item_Model_Test.php | 16 ++++- modules/gallery/tests/Movie_Helper_Test.php | 36 +++++++++-- modules/gallery/tests/Photo_Helper_Test.php | 18 +++++- modules/watermark/controllers/admin_watermarks.php | 13 ++-- 9 files changed, 139 insertions(+), 50 deletions(-) (limited to 'modules/gallery/tests/Movie_Helper_Test.php') diff --git a/modules/gallery/helpers/gallery_graphics.php b/modules/gallery/helpers/gallery_graphics.php index b78bd9a7..eb76353f 100644 --- a/modules/gallery/helpers/gallery_graphics.php +++ b/modules/gallery/helpers/gallery_graphics.php @@ -172,6 +172,11 @@ class gallery_graphics_Core { module::event("graphics_composite_completed", $input_file, $output_file, $options, $item); } catch (ErrorException $e) { + // Unlike rotate and resize, composite catches its exceptions here. This is because + // composite is typically called for watermarks. If during thumb/resize generation + // the watermark fails, we'd still like the image resized, just without its watermark. + // If the exception isn't caught here, graphics::generate will replace it with a + // placeholder. Kohana_Log::add("error", $e->getMessage()); } } diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php index 4df57fba..e34af018 100644 --- a/modules/gallery/helpers/graphics.php +++ b/modules/gallery/helpers/graphics.php @@ -224,7 +224,16 @@ class graphics_Core { graphics::_replace_image_with_placeholder($item, "resize"); } graphics::_replace_image_with_placeholder($item, "thumb"); - graphics::_update_item_dimensions($item); + try { + graphics::_update_item_dimensions($item); + } catch (Exception $e) { + // Looks like get_file_metadata couldn't identify our placeholders. We should never get + // here, but in the odd case we do, we need to do something. Let's put in hardcoded values. + if ($item->is_photo()) { + list ($item->resize_width, $item->resize_height) = array(200, 200); + } + list ($item->thumb_width, $item->thumb_height) = array(200, 200); + } $item->save(); throw $e; } diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php index 6844771b..d4b907a2 100644 --- a/modules/gallery/helpers/movie.php +++ b/modules/gallery/helpers/movie.php @@ -192,8 +192,16 @@ class movie_Core { $metadata->extension = strtolower($extension); } - // Run movie_get_file_metadata events which can modify the class, then return results. + // Run movie_get_file_metadata events which can modify the class. module::event("movie_get_file_metadata", $file_path, $metadata); + + // If the post-events results are invalid, throw an exception. Note that, unlike photos, having + // zero width and height isn't considered invalid (as is the case when FFmpeg isn't installed). + if (!$metadata->mime_type || !$metadata->extension || + ($metadata->mime_type != legal_file::get_movie_types_by_extension($metadata->extension))) { + throw new Exception("@todo ILLEGAL_OR_UNINDENTIFIABLE_FILE"); + } + return array($metadata->width, $metadata->height, $metadata->mime_type, $metadata->extension, $metadata->duration); } diff --git a/modules/gallery/helpers/photo.php b/modules/gallery/helpers/photo.php index 51e51507..2d32f0d3 100644 --- a/modules/gallery/helpers/photo.php +++ b/modules/gallery/helpers/photo.php @@ -133,8 +133,15 @@ class photo_Core { $metadata->height = 0; } - // Run photo_get_file_metadata events which can modify the class, then return results. + // Run photo_get_file_metadata events which can modify the class. module::event("photo_get_file_metadata", $file_path, $metadata); + + // If the post-events results are invalid, throw an exception. + if (!$metadata->width || !$metadata->height || !$metadata->mime_type || !$metadata->extension || + ($metadata->mime_type != legal_file::get_photo_types_by_extension($metadata->extension))) { + throw new Exception("@todo ILLEGAL_OR_UNINDENTIFIABLE_FILE"); + } + return array($metadata->width, $metadata->height, $metadata->mime_type, $metadata->extension); } } diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index 197d3057..33b8a89d 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -21,6 +21,7 @@ class Item_Model_Core extends ORM_MPTT { protected $children = "items"; protected $sorting = array(); public $data_file = null; + private $data_file_error = null; public function __construct($id=null) { parent::__construct($id); @@ -378,18 +379,26 @@ class Item_Model_Core extends ORM_MPTT { // Get the width, height and mime type from our data file for photos and movies. if ($this->is_photo() || $this->is_movie()) { - if ($this->is_photo()) { - list ($this->width, $this->height, $this->mime_type, $extension) = - photo::get_file_metadata($this->data_file); - } else if ($this->is_movie()) { - list ($this->width, $this->height, $this->mime_type, $extension) = - movie::get_file_metadata($this->data_file); - } - - // Force an extension onto the name if necessary - $pi = pathinfo($this->data_file); - if (empty($pi["extension"])) { - $this->name = "{$this->name}.$extension"; + try { + if ($this->is_photo()) { + list ($this->width, $this->height, $this->mime_type, $extension) = + photo::get_file_metadata($this->data_file); + } else if ($this->is_movie()) { + list ($this->width, $this->height, $this->mime_type, $extension) = + movie::get_file_metadata($this->data_file); + } + + // Force an extension onto the name if necessary + $pi = pathinfo($this->data_file); + if (empty($pi["extension"])) { + $this->name = "{$this->name}.$extension"; + } + + // Data file valid - make sure the flag is reset to false. + $this->data_file_error = false; + } catch (Exception $e) { + // Data file invalid - set the flag so it's reported during item validation. + $this->data_file_error = true; } } @@ -436,17 +445,24 @@ class Item_Model_Core extends ORM_MPTT { // appropriate for its data. We don't try to preserve the name of the data file, though, // because the name is typically a temporary randomly-generated name. if (isset($this->data_file)) { - $extension = pathinfo($this->data_file, PATHINFO_EXTENSION); - $new_name = pathinfo($this->name, PATHINFO_FILENAME) . ".$extension"; - if (!empty($extension) && strcmp($this->name, $new_name)) { - $this->name = $new_name; - } - if ($this->is_photo()) { - list ($this->width, $this->height, $this->mime_type, $extension) = - photo::get_file_metadata($this->data_file); - } else if ($this->is_movie()) { - list ($this->width, $this->height, $this->mime_type, $extension) = - movie::get_file_metadata($this->data_file); + try { + $extension = pathinfo($this->data_file, PATHINFO_EXTENSION); + $new_name = pathinfo($this->name, PATHINFO_FILENAME) . ".$extension"; + if (!empty($extension) && strcmp($this->name, $new_name)) { + $this->name = $new_name; + } + if ($this->is_photo()) { + list ($this->width, $this->height, $this->mime_type, $extension) = + photo::get_file_metadata($this->data_file); + } else if ($this->is_movie()) { + list ($this->width, $this->height, $this->mime_type, $extension) = + movie::get_file_metadata($this->data_file); + } + // Data file valid - make sure the flag is reset to false. + $this->data_file_error = false; + } catch (Exception $e) { + // Data file invalid - set the flag so it's reported during item validation. + $this->data_file_error = true; } } @@ -524,13 +540,6 @@ class Item_Model_Core extends ORM_MPTT { // Replace the data file, if requested. if ($this->data_file && ($this->is_photo() || $this->is_movie())) { copy($this->data_file, $this->file_path()); - - // Get the width, height and mime type from our data file for photos and movies. - if ($this->is_photo()) { - list ($this->width, $this->height) = photo::get_file_metadata($this->file_path()); - } else if ($this->is_movie()) { - list ($this->width, $this->height) = movie::get_file_metadata($this->file_path()); - } $this->thumb_dirty = 1; $this->resize_dirty = 1; } @@ -966,6 +975,8 @@ class Item_Model_Core extends ORM_MPTT { $v->add_error("name", "bad_data_file_path"); } else if (filesize($this->data_file) == 0) { $v->add_error("name", "empty_data_file"); + } else if ($this->data_file_error) { + $v->add_error("name", "invalid_data_file"); } } diff --git a/modules/gallery/tests/Item_Model_Test.php b/modules/gallery/tests/Item_Model_Test.php index a1c5bce6..a93498dd 100644 --- a/modules/gallery/tests/Item_Model_Test.php +++ b/modules/gallery/tests/Item_Model_Test.php @@ -445,13 +445,25 @@ class Item_Model_Test extends Gallery_Unit_Test_Case { $photo->set_data_file(MODPATH . "gallery/tests/Item_Model_Test.php"); $photo->save(); } catch (ORM_Validation_Exception $e) { - $this->assert_same(array("mime_type" => "invalid", "name" => "illegal_data_file_extension"), - $e->validation->errors()); + $this->assert_same(array("name" => "illegal_data_file_extension"), $e->validation->errors()); return; // pass } $this->assert_true(false, "Shouldn't get here"); } + public function unsafe_data_file_replacement_with_valid_extension_test() { + $temp_file = TMPPATH . "masquerading_php.jpg"; + copy(MODPATH . "gallery/tests/Item_Model_Test.php", $temp_file); + try { + $photo = test::random_photo(); + $photo->set_data_file($temp_file); + $photo->save(); + } catch (ORM_Validation_Exception $e) { + $this->assert_same(array("name" => "invalid_data_file"), $e->validation->errors()); + return; // pass + } + } + public function urls_test() { $photo = test::random_photo(); $this->assert_true( diff --git a/modules/gallery/tests/Movie_Helper_Test.php b/modules/gallery/tests/Movie_Helper_Test.php index 0c262620..03fa2da9 100644 --- a/modules/gallery/tests/Movie_Helper_Test.php +++ b/modules/gallery/tests/Movie_Helper_Test.php @@ -64,18 +64,42 @@ class Movie_Helper_Test extends Gallery_Unit_Test_Case { public function get_file_metadata_with_no_extension_test() { copy(MODPATH . "gallery/tests/test.flv", TMPPATH . "test_flv_with_no_extension"); - $this->assert_equal(array(360, 288, null, null, 6.00), - movie::get_file_metadata(TMPPATH . "test_flv_with_no_extension")); + // Since mime type and extension are based solely on the filename, this is considered invalid. + try { + $metadata = movie::get_file_metadata(TMPPATH . "test_flv_with_no_extension"); + $this->assert_true(false, "Shouldn't get here"); + } catch (Exception $e) { + // pass + } } public function get_file_metadata_with_illegal_extension_test() { - $this->assert_equal(array(0, 0, null, null, 0), - movie::get_file_metadata(MODPATH . "gallery/tests/Movie_Helper_Test.php")); + try { + $metadata = movie::get_file_metadata(MODPATH . "gallery/tests/Movie_Helper_Test.php"); + $this->assert_true(false, "Shouldn't get here"); + } catch (Exception $e) { + // pass + } } public function get_file_metadata_with_illegal_extension_but_valid_file_contents_test() { copy(MODPATH . "gallery/tests/test.flv", TMPPATH . "test_flv_with_php_extension.php"); - $this->assert_equal(array(360, 288, null, null, 6.00), - movie::get_file_metadata(TMPPATH . "test_flv_with_php_extension.php")); + // Since mime type and extension are based solely on the filename, this is considered invalid. + try { + $metadata = movie::get_file_metadata(TMPPATH . "test_flv_with_php_extension.php"); + $this->assert_true(false, "Shouldn't get here"); + } catch (Exception $e) { + // pass + } + } + + public function get_file_metadata_with_valid_extension_but_illegal_file_contents_test() { + copy(MODPATH . "gallery/tests/Photo_Helper_Test.php", TMPPATH . "test_php_with_flv_extension.flv"); + // Since mime type and extension are based solely on the filename, this is considered valid. + // Of course, FFmpeg cannot extract width, height, or duration from the file. Note that this + // isn't a really a security problem, since the filename doesn't have a php extension and + // therefore will never be executed. + $this->assert_equal(array(0, 0, "video/x-flv", "flv", 0), + movie::get_file_metadata(TMPPATH . "test_php_with_flv_extension.flv")); } } diff --git a/modules/gallery/tests/Photo_Helper_Test.php b/modules/gallery/tests/Photo_Helper_Test.php index 5207a6db..79b5ccfd 100644 --- a/modules/gallery/tests/Photo_Helper_Test.php +++ b/modules/gallery/tests/Photo_Helper_Test.php @@ -40,8 +40,12 @@ class Photo_Helper_Test extends Gallery_Unit_Test_Case { } public function get_file_metadata_with_illegal_extension_test() { - $this->assert_equal(array(0, 0, null, null), - photo::get_file_metadata(MODPATH . "gallery/tests/Photo_Helper_Test.php")); + try { + $metadata = photo::get_file_metadata(MODPATH . "gallery/tests/Photo_Helper_Test.php"); + $this->assert_true(false, "Shouldn't get here"); + } catch (Exception $e) { + // pass + } } public function get_file_metadata_with_illegal_extension_but_valid_file_contents_test() { @@ -53,4 +57,14 @@ class Photo_Helper_Test extends Gallery_Unit_Test_Case { $this->assert_equal(array(1024, 768, "image/jpeg", "jpg"), photo::get_file_metadata(TMPPATH . "test_jpg_with_php_extension.php")); } + + public function get_file_metadata_with_valid_extension_but_illegal_file_contents_test() { + copy(MODPATH . "gallery/tests/Photo_Helper_Test.php", TMPPATH . "test_php_with_jpg_extension.jpg"); + try { + $metadata = photo::get_file_metadata(TMPPATH . "test_php_with_jpg_extension.jpg"); + $this->assert_true(false, "Shouldn't get here"); + } catch (Exception $e) { + // pass + } + } } diff --git a/modules/watermark/controllers/admin_watermarks.php b/modules/watermark/controllers/admin_watermarks.php index 27c2efc9..59bb7fa9 100644 --- a/modules/watermark/controllers/admin_watermarks.php +++ b/modules/watermark/controllers/admin_watermarks.php @@ -102,18 +102,17 @@ class Admin_Watermarks_Controller extends Admin_Controller { $name = preg_replace("/uploadfile-[^-]+-(.*)/", '$1', $pathinfo["basename"]); $name = legal_file::smash_extensions($name); - list ($width, $height, $mime_type, $extension) = photo::get_file_metadata($file); - if (!$width || !$height || !$mime_type || !$extension || - !legal_file::get_photo_extensions($extension)) { - message::error(t("Invalid or unidentifiable image file")); - @unlink($file); - return; - } else { + try { + list ($width, $height, $mime_type, $extension) = photo::get_file_metadata($file); // Force correct, legal extension type on file, which will be of our canonical type // (i.e. all lowercase, jpg instead of jpeg, etc.). This renaming prevents the issues // addressed in ticket #1855, where an image that looked valid (header said jpg) with a // php extension was previously accepted without changing its extension. $name = legal_file::change_extension($name, $extension); + } catch (Exception $e) { + message::error(t("Invalid or unidentifiable image file")); + @unlink($file); + return; } rename($file, VARPATH . "modules/watermark/$name"); -- cgit v1.2.3