From ffbaa7bf82750814b6b31c8c83ee11ad25a41196 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sun, 13 May 2012 21:09:26 -0700 Subject: Follow on for #1845 - handle paths with dots in them properly. --- modules/gallery/helpers/legal_file.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/legal_file.php b/modules/gallery/helpers/legal_file.php index af6472ca..075de9cd 100644 --- a/modules/gallery/helpers/legal_file.php +++ b/modules/gallery/helpers/legal_file.php @@ -89,7 +89,7 @@ class legal_file_Core { if (strpos($filename, ".") === false) { return "{$filename}.{$new_ext}"; } else { - return preg_replace("/\..*?$/", ".{$new_ext}", $filename); + return preg_replace("/\.[^\.]*?$/", ".{$new_ext}", $filename); } } } -- cgit v1.2.3 From aac18ef8339054e134fa3e52788a80e6907dfba5 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Tue, 15 May 2012 15:53:38 -0700 Subject: Don't allow new albums with a slug that matches a controller - put up a message telling the user that it's a reserved address. Partial fix for #95. --- modules/gallery/helpers/album.php | 4 ++++ modules/gallery/models/item.php | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/album.php b/modules/gallery/helpers/album.php index 23d59eea..0945e4d9 100644 --- a/modules/gallery/helpers/album.php +++ b/modules/gallery/helpers/album.php @@ -39,6 +39,8 @@ class album_Core { ->error_messages("length", t("Your directory name is too long")) ->error_messages("conflict", t("There is already a movie, photo or album with this name")); $group->input("slug")->label(t("Internet Address")) + ->error_messages( + "reserved", t("This address is reserved and can't be used.")) ->error_messages( "not_url_safe", t("The internet address should contain only letters, numbers, hyphens and underscores")) @@ -75,6 +77,8 @@ class album_Core { $group->input("slug")->label(t("Internet Address"))->value($parent->slug) ->error_messages( "conflict", t("There is already a movie, photo or album with this internet address")) + ->error_messages( + "reserved", t("This address is reserved and can't be used.")) ->error_messages( "not_url_safe", t("The internet address should contain only letters, numbers, hyphens and underscores")) diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index 98a2c4df..992af0cc 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -833,6 +833,11 @@ class Item_Model_Core extends ORM_MPTT { $v->add_error("name", "conflict"); return; } + + if ($this->parent_id == 1 && Kohana::auto_load("{$this->slug}_Controller")) { + $v->add_error("slug", "reserved"); + return; + } } /** -- cgit v1.2.3 From 9e2ea2ffedb22f83137db4e5ba4c06b91f11e09d Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Thu, 17 May 2012 20:25:27 -0700 Subject: Smash multiple extensions down into a single one when accepting file uploads. Fixes #1872. --- modules/gallery/controllers/uploader.php | 4 ++++ modules/gallery/helpers/legal_file.php | 16 ++++++++++++++++ modules/gallery/models/item.php | 10 +++++++++- modules/gallery/tests/Item_Model_Test.php | 3 ++- modules/gallery/tests/Legal_File_Helper_Test.php | 10 ++++++++++ modules/watermark/controllers/admin_watermarks.php | 1 + 6 files changed, 42 insertions(+), 2 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/controllers/uploader.php b/modules/gallery/controllers/uploader.php index 906373b6..4ea55ff6 100644 --- a/modules/gallery/controllers/uploader.php +++ b/modules/gallery/controllers/uploader.php @@ -63,6 +63,10 @@ class Uploader_Controller extends Controller { $item->parent_id = $album->id; $item->set_data_file($temp_filename); + // Remove double extensions from the filename - they'll be disallowed in the model but if + // we don't do it here then it'll result in a failed upload. + $item->name = legal_file::smash_extensions($item->name); + $path_info = @pathinfo($temp_filename); if (array_key_exists("extension", $path_info) && in_array(strtolower($path_info["extension"]), array("flv", "mp4", "m4v"))) { diff --git a/modules/gallery/helpers/legal_file.php b/modules/gallery/helpers/legal_file.php index 075de9cd..bd48d7b7 100644 --- a/modules/gallery/helpers/legal_file.php +++ b/modules/gallery/helpers/legal_file.php @@ -92,4 +92,20 @@ class legal_file_Core { return preg_replace("/\.[^\.]*?$/", ".{$new_ext}", $filename); } } + + /** + * Reduce the given file to having a single extension. + */ + static function smash_extensions($filename) { + $parts = pathinfo($filename); + $result = ""; + if ($parts["dirname"] != ".") { + $result .= $parts["dirname"] . "/"; + } + $parts["filename"] = str_replace(".", "_", $parts["filename"]); + $parts["filename"] = preg_replace("/[_]+/", "_", $parts["filename"]); + $parts["filename"] = trim($parts["filename"], "_"); + $result .= "{$parts['filename']}.{$parts['extension']}"; + return $result; + } } diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index 992af0cc..903dadad 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -797,11 +797,19 @@ class Item_Model_Core extends ORM_MPTT { if (strpos($this->name, "/") !== false) { $v->add_error("name", "no_slashes"); return; - } else if (rtrim($this->name, ".") !== $this->name) { + } + + if (rtrim($this->name, ".") !== $this->name) { $v->add_error("name", "no_trailing_period"); return; } + // Do not accept files with double extensions, they can cause problems on some + // versions of Apache. + if (substr_count($this->name, ".") > 1) { + $v->add_error("name", "illegal_data_file_extension"); + } + if ($this->is_movie() || $this->is_photo()) { $ext = pathinfo($this->name, PATHINFO_EXTENSION); diff --git a/modules/gallery/tests/Item_Model_Test.php b/modules/gallery/tests/Item_Model_Test.php index 6d40230f..876fc137 100644 --- a/modules/gallery/tests/Item_Model_Test.php +++ b/modules/gallery/tests/Item_Model_Test.php @@ -490,7 +490,8 @@ class Item_Model_Test extends Gallery_Unit_Test_Case { } public function illegal_extension_test() { - foreach (array("test.php", "test.PHP", "test.php5", "test.php4", "test.pl") as $name) { + foreach (array("test.php", "test.PHP", "test.php5", "test.php4", + "test.pl", "test.php.png") as $name) { try { $photo = test::random_photo_unsaved(item::root()); $photo->name = $name; diff --git a/modules/gallery/tests/Legal_File_Helper_Test.php b/modules/gallery/tests/Legal_File_Helper_Test.php index 6f94c9cd..d80bcafe 100644 --- a/modules/gallery/tests/Legal_File_Helper_Test.php +++ b/modules/gallery/tests/Legal_File_Helper_Test.php @@ -35,4 +35,14 @@ class Legal_File_Helper_Test extends Gallery_Unit_Test_Case { "/website/foo.com/VID_20120513_105421.jpg", legal_file::change_extension("/website/foo.com/VID_20120513_105421.mp4", "jpg")); } + + public function smash_extensions_test() { + $this->assert_equal("foo_bar.jpg", legal_file::smash_extensions("foo.bar.jpg")); + $this->assert_equal("foo_bar_baz.jpg", legal_file::smash_extensions("foo.bar.baz.jpg")); + $this->assert_equal("foo_bar_baz.jpg", legal_file::smash_extensions("foo.bar.baz.jpg")); + $this->assert_equal("foo_bar_baz.jpg", legal_file::smash_extensions("...foo...bar..baz...jpg")); + $this->assert_equal("/path/to/foo_bar.jpg", legal_file::smash_extensions("/path/to/foo.bar.jpg")); + $this->assert_equal("/path/to.to/foo_bar.jpg", legal_file::smash_extensions("/path/to.to/foo.bar.jpg")); + $this->assert_equal("foo_bar-12345678.jpg", legal_file::smash_extensions("foo.bar-12345678.jpg")); + } } \ No newline at end of file diff --git a/modules/watermark/controllers/admin_watermarks.php b/modules/watermark/controllers/admin_watermarks.php index 92a44a86..a80f82a9 100644 --- a/modules/watermark/controllers/admin_watermarks.php +++ b/modules/watermark/controllers/admin_watermarks.php @@ -98,6 +98,7 @@ class Admin_Watermarks_Controller extends Admin_Controller { $pathinfo = pathinfo($file); // Forge prefixes files with "uploadfile-xxxxxxx" for uniqueness $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))) { -- cgit v1.2.3 From a9be0691d9efd84cbf5a9f05236caf4df23bcfdb Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sat, 19 May 2012 11:28:46 -0700 Subject: Create an ajax response framework that inserts tags to guard against UTF-7, and create a $.gallery_autocomplete variant of jQuery's autocomplete that expects the first line to be a tag and discards it. More complete fix for #1871. --- lib/gallery.common.js | 28 +++++++++++++++++++ modules/g2_import/controllers/admin_g2_import.php | 2 +- modules/g2_import/views/admin_g2_import.html.php | 2 +- modules/gallery/helpers/ajax.php | 31 ++++++++++++++++++++++ .../server_add/controllers/admin_server_add.php | 3 ++- modules/server_add/views/admin_server_add.html.php | 2 +- modules/tag/controllers/tags.php | 4 +-- modules/tag/helpers/tag_event.php | 4 +-- modules/tag/views/tag_block.html.php | 2 +- 9 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 modules/gallery/helpers/ajax.php (limited to 'modules/gallery/helpers') diff --git a/lib/gallery.common.js b/lib/gallery.common.js index b499a2cd..755218f5 100644 --- a/lib/gallery.common.js +++ b/lib/gallery.common.js @@ -222,4 +222,32 @@ }); }; + // Augment jQuery autocomplete to expect the first response line to + // be a tag that protects against UTF-7 attacks. + $.fn.gallery_autocomplete = function(url, options) { + // Drop the first response - it should be a meta tag + options.parse = function(data) { + var parsed = []; + var rows = data.split("\n"); + if (rows[0].indexOf(" tag in first line of autocomplete response'; + } + rows.shift(); // drop tag + for (var i=0; i < rows.length; i++) { + var row = $.trim(rows[i]); + if (row) { + row = row.split("|"); + parsed[parsed.length] = { + data: row, + value: row[0], + result: row[0] + }; + } + } + return parsed; + }; + + $(this).autocomplete(url, options); + }; + })(jQuery); diff --git a/modules/g2_import/controllers/admin_g2_import.php b/modules/g2_import/controllers/admin_g2_import.php index b07082c9..5edd2a1b 100644 --- a/modules/g2_import/controllers/admin_g2_import.php +++ b/modules/g2_import/controllers/admin_g2_import.php @@ -113,7 +113,7 @@ class Admin_g2_import_Controller extends Admin_Controller { } } - print implode("\n", $directories); + ajax::response(implode("\n", $directories)); } private function _get_import_form() { diff --git a/modules/g2_import/views/admin_g2_import.html.php b/modules/g2_import/views/admin_g2_import.html.php index 9c4eb840..22e19f5b 100644 --- a/modules/g2_import/views/admin_g2_import.html.php +++ b/modules/g2_import/views/admin_g2_import.html.php @@ -3,7 +3,7 @@ script("jquery.autocomplete.js") ?>