From 891a24151ee7dd197c623b4f482f260009d67096 Mon Sep 17 00:00:00 2001
From: shadlaws <shad@shadlaws.com>
Date: Wed, 27 Feb 2013 07:11:52 +0100
Subject: #2021 - Cleanup thumb_dirty and resize_dirty instances. - g2_import:
 changed "false" assignment to "0" assignment for consistency. -
 admin_theme_options: removed unused variables (they're called/used nowhere
 else). - graphics: removed stanza that clears thumb_dirty and resize_dirty
 and returns if we have no ops.  This has no effect on Gallery currently (for
 one, graphics::generate doesn't normally get called on an item with no dirty
 flags), but can inconsistently set resize_dirty of albums and movies to 0
 where it's otherwise left at 1.  Going forward, it may be useful to be
 consistent here. - gallery_installer: added v57 stanza to correct any
 resize_dirty flags of movies/albums that were previously reset to 0. -
 module.info, install.sql: update to v57

---
 installer/install.sql | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'installer/install.sql')

diff --git a/installer/install.sql b/installer/install.sql
index b89d6b9b..f4938f6f 100644
--- a/installer/install.sql
+++ b/installer/install.sql
@@ -245,7 +245,7 @@ CREATE TABLE {modules} (
   KEY `weight` (`weight`)
 ) AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
 /*!40101 SET character_set_client = @saved_cs_client */;
-INSERT INTO {modules} VALUES (1,1,'gallery',56,1);
+INSERT INTO {modules} VALUES (1,1,'gallery',57,1);
 INSERT INTO {modules} VALUES (2,1,'user',4,2);
 INSERT INTO {modules} VALUES (3,1,'comment',7,3);
 INSERT INTO {modules} VALUES (4,1,'organize',4,4);
-- 
cgit v1.2.3


From ed20798b99c0c6ab90e4d141ff74d7c2ca606ae7 Mon Sep 17 00:00:00 2001
From: shadlaws <shad@shadlaws.com>
Date: Tue, 12 Mar 2013 12:14:34 +0100
Subject: #2057 - Revise item name and slug validation - backslashes, refactor,
 error messages. - disallowed backslashes in item validation. - refactored the
 validation logic in the item model a bit. - added no_backslash error messages
 in edit album/photo/movie forms. - fixed error messages in add album forum
 (some missing, some text different from edit) - added unit tests - updated to
 v58 to correct any existing backslashes in item names

---
 installer/install.sql                         |  2 +-
 modules/gallery/helpers/album.php             |  9 ++++--
 modules/gallery/helpers/gallery_installer.php | 20 ++++++++++++
 modules/gallery/helpers/movie.php             |  1 +
 modules/gallery/helpers/photo.php             |  1 +
 modules/gallery/models/item.php               | 44 +++++++++++++++++---------
 modules/gallery/module.info                   |  2 +-
 modules/gallery/tests/Item_Model_Test.php     | 45 ++++++++++++++++++++++++++-
 8 files changed, 104 insertions(+), 20 deletions(-)

(limited to 'installer/install.sql')

diff --git a/installer/install.sql b/installer/install.sql
index f4938f6f..3f63cf7c 100644
--- a/installer/install.sql
+++ b/installer/install.sql
@@ -245,7 +245,7 @@ CREATE TABLE {modules} (
   KEY `weight` (`weight`)
 ) AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
 /*!40101 SET character_set_client = @saved_cs_client */;
-INSERT INTO {modules} VALUES (1,1,'gallery',57,1);
+INSERT INTO {modules} VALUES (1,1,'gallery',58,1);
 INSERT INTO {modules} VALUES (2,1,'user',4,2);
 INSERT INTO {modules} VALUES (3,1,'comment',7,3);
 INSERT INTO {modules} VALUES (4,1,'organize',4,4);
diff --git a/modules/gallery/helpers/album.php b/modules/gallery/helpers/album.php
index 23aed8ac..fe6b03fc 100644
--- a/modules/gallery/helpers/album.php
+++ b/modules/gallery/helpers/album.php
@@ -34,11 +34,15 @@ class album_Core {
       ->error_messages("length", t("Your title is too long"));
     $group->textarea("description")->label(t("Description"));
     $group->input("name")->label(t("Directory name"))
-      ->error_messages("no_slashes", t("The directory name can't contain the \"/\" character"))
+      ->error_messages("no_slashes", t("The directory name can't contain a \"/\""))
+      ->error_messages("no_backslashes", t("The directory name can't contain a \"\\\""))
+      ->error_messages("no_trailing_period", t("The directory name can't end in \".\""))
       ->error_messages("required", t("You must provide a directory name"))
       ->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(
+        "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(
@@ -64,13 +68,14 @@ class album_Core {
     $group = $form->group("edit_item")->label(t("Edit Album"));
 
     $group->input("title")->label(t("Title"))->value($parent->title)
-        ->error_messages("required", t("You must provide a title"))
+      ->error_messages("required", t("You must provide a title"))
       ->error_messages("length", t("Your title is too long"));
     $group->textarea("description")->label(t("Description"))->value($parent->description);
     if ($parent->id != 1) {
       $group->input("name")->label(t("Directory Name"))->value($parent->name)
         ->error_messages("conflict", t("There is already a movie, photo or album with this name"))
         ->error_messages("no_slashes", t("The directory name can't contain a \"/\""))
+        ->error_messages("no_backslashes", t("The directory name can't contain a \"\\\""))
         ->error_messages("no_trailing_period", t("The directory name can't end in \".\""))
         ->error_messages("required", t("You must provide a directory name"))
         ->error_messages("length", t("Your directory name is too long"));
diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php
index d49be83f..f1604150 100644
--- a/modules/gallery/helpers/gallery_installer.php
+++ b/modules/gallery/helpers/gallery_installer.php
@@ -809,6 +809,26 @@ class gallery_installer {
         ->execute();
       module::set_version("gallery", $version = 57);
     }
+
+    if ($version == 57) {
+      // In v58 we changed the Item_Model validation code to disallow files or directories with
+      // backslashes in them, and we need to fix any existing items that have them.  This is
+      // pretty unlikely, as having backslashes would have probably already caused other issues for
+      // users, but we should check anyway.  This might be slow, but if it times out it can just
+      // pick up where it left off.
+      foreach (db::build()
+               ->from("items")
+               ->select("id")
+               ->where(db::expr("`name` REGEXP '\\\\\\\\'"), "=", 1)  // one \, 3x escaped
+               ->order_by("id", "asc")
+               ->execute() as $row) {
+        set_time_limit(30);
+        $item = ORM::factory("item", $row->id);
+        $item->name = str_replace("\\", "_", $item->name);
+        $item->save();
+      }
+      module::set_version("gallery", $version = 58);
+    }
   }
 
   static function uninstall() {
diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php
index 2f190881..4613df61 100644
--- a/modules/gallery/helpers/movie.php
+++ b/modules/gallery/helpers/movie.php
@@ -38,6 +38,7 @@ class movie_Core {
       ->error_messages(
         "conflict", t("There is already a movie, photo or album with this name"))
       ->error_messages("no_slashes", t("The movie name can't contain a \"/\""))
+      ->error_messages("no_backslashes", t("The movie name can't contain a \"\\\""))
       ->error_messages("no_trailing_period", t("The movie name can't end in \".\""))
       ->error_messages("illegal_data_file_extension", t("You cannot change the movie file extension"))
       ->error_messages("required", t("You must provide a movie file name"))
diff --git a/modules/gallery/helpers/photo.php b/modules/gallery/helpers/photo.php
index 004cc7c4..ecf81e66 100644
--- a/modules/gallery/helpers/photo.php
+++ b/modules/gallery/helpers/photo.php
@@ -35,6 +35,7 @@ class photo_Core {
     $group->input("name")->label(t("Filename"))->value($photo->name)
       ->error_messages("conflict", t("There is already a movie, photo or album with this name"))
       ->error_messages("no_slashes", t("The photo name can't contain a \"/\""))
+      ->error_messages("no_backslashes", t("The photo name can't contain a \"\\\""))
       ->error_messages("no_trailing_period", t("The photo name can't end in \".\""))
       ->error_messages("illegal_data_file_extension", t("You cannot change the photo file extension"))
       ->error_messages("required", t("You must provide a photo file name"))
diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php
index 1e16d307..b708c503 100644
--- a/modules/gallery/models/item.php
+++ b/modules/gallery/models/item.php
@@ -889,12 +889,17 @@ class Item_Model_Core extends ORM_MPTT {
   }
 
   /**
-   * Validate that the desired slug does not conflict.
+   * Validate the item slug.  It can return the following error messages:
+   * - not_url_safe: has illegal characters
+   * - conflict: has conflicting slug
+   * - reserved (items in root only): has same slug as a controller
    */
   public function valid_slug(Validation $v, $field) {
     if (preg_match("/[^A-Za-z0-9-_]/", $this->slug)) {
       $v->add_error("slug", "not_url_safe");
-    } else if (db::build()
+    }
+
+    if (db::build()
         ->from("items")
         ->where("parent_id", "=", $this->parent_id)
         ->where("id", "<>", $this->id)
@@ -902,11 +907,20 @@ class Item_Model_Core extends ORM_MPTT {
         ->count_records()) {
       $v->add_error("slug", "conflict");
     }
+
+    if ($this->parent_id == 1 && Kohana::auto_load("{$this->slug}_Controller")) {
+      $v->add_error("slug", "reserved");
+      return;
+    }
   }
 
   /**
-   * Validate the item name.  It can't conflict with other names, can't contain slashes or
-   * trailing periods.
+   * Validate the item name.  It can return the following error messages:
+   * - no_slashes: contains slashes
+   * - no_backslashes: contains backslashes
+   * - no_trailing_period: has a trailing period
+   * - illegal_data_file_extension (non-albums only): has double, no, or illegal extension
+   * - conflict: has conflicting name
    */
   public function valid_name(Validation $v, $field) {
     if (strpos($this->name, "/") !== false) {
@@ -914,18 +928,23 @@ class Item_Model_Core extends ORM_MPTT {
       return;
     }
 
-    if (rtrim($this->name, ".") !== $this->name) {
-      $v->add_error("name", "no_trailing_period");
+    if (strpos($this->name, "\\") !== false) {
+      $v->add_error("name", "no_backslashes");
       return;
     }
 
-    // Do not accept files with double extensions, they can cause problems on some
-    // versions of Apache.
-    if (!$this->is_album() && substr_count($this->name, ".") > 1) {
-      $v->add_error("name", "illegal_data_file_extension");
+    if (rtrim($this->name, ".") !== $this->name) {
+      $v->add_error("name", "no_trailing_period");
+      return;
     }
 
     if ($this->is_movie() || $this->is_photo()) {
+      if (substr_count($this->name, ".") > 1) {
+        // Do not accept files with double extensions, as they can
+        // cause problems on some versions of Apache.
+        $v->add_error("name", "illegal_data_file_extension");
+      }
+
       $ext = pathinfo($this->name, PATHINFO_EXTENSION);
 
       if (!$this->loaded() && !$ext) {
@@ -967,11 +986,6 @@ class Item_Model_Core extends ORM_MPTT {
         return;
       }
     }
-
-    if ($this->parent_id == 1 && Kohana::auto_load("{$this->slug}_Controller")) {
-      $v->add_error("slug", "reserved");
-      return;
-    }
   }
 
   /**
diff --git a/modules/gallery/module.info b/modules/gallery/module.info
index 7f49b72e..49023e45 100644
--- a/modules/gallery/module.info
+++ b/modules/gallery/module.info
@@ -1,6 +1,6 @@
 name = "Gallery 3"
 description = "Gallery core application"
-version = 57
+version = 58
 author_name = "Gallery Team"
 author_url = "http://codex.galleryproject.org/Gallery:Team"
 info_url = "http://codex.galleryproject.org/Gallery3:Modules:gallery"
diff --git a/modules/gallery/tests/Item_Model_Test.php b/modules/gallery/tests/Item_Model_Test.php
index 83c9f79d..e3a4a6b7 100644
--- a/modules/gallery/tests/Item_Model_Test.php
+++ b/modules/gallery/tests/Item_Model_Test.php
@@ -124,13 +124,56 @@ class Item_Model_Test extends Gallery_Unit_Test_Case {
     $this->assert_equal($fullsize_file, file_get_contents($photo->file_path()));
   }
 
-  public function item_rename_wont_accept_slash_test() {
+  public function photo_rename_wont_accept_slash_test() {
     $item = test::random_photo();
     $item->name = "/no_slashes/allowed/";
     $item->save();
     $this->assert_equal("no_slashes_allowed.jpg", $item->name);
   }
 
+  public function photo_rename_wont_accept_backslash_test() {
+    $item = test::random_photo();
+    $item->name = "\\no_backslashes\\allowed\\";
+    $item->save();
+    $this->assert_equal("no_backslashes_allowed.jpg", $item->name);
+  }
+
+  public function album_rename_wont_accept_slash_test() {
+    try {
+      $item = test::random_album();
+      $item->name = "/no_album_slashes/allowed/";
+      $item->save();
+    } catch (ORM_Validation_Exception $e) {
+      $this->assert_same(array("name" => "no_slashes"), $e->validation->errors());
+      return;  // pass
+    }
+    $this->assert_true(false, "Shouldn't get here");
+  }
+
+  public function album_rename_wont_accept_backslash_test() {
+    try {
+      $item = test::random_album();
+      $item->name = "\\no_album_backslashes\\allowed\\";
+      $item->save();
+    } catch (ORM_Validation_Exception $e) {
+      $this->assert_same(array("name" => "no_backslashes"), $e->validation->errors());
+      return;  // pass
+    }
+    $this->assert_true(false, "Shouldn't get here");
+  }
+
+  public function album_rename_wont_accept_trailing_period_test() {
+    try {
+      $item = test::random_album();
+      $item->name = ".no_trailing_period.allowed.";
+      $item->save();
+    } catch (ORM_Validation_Exception $e) {
+      $this->assert_same(array("name" => "no_trailing_period"), $e->validation->errors());
+      return;  // pass
+    }
+    $this->assert_true(false, "Shouldn't get here");
+  }
+
   public function move_album_test() {
     $album2 = test::random_album();
     $album1 = test::random_album($album2);
-- 
cgit v1.2.3

