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. --- 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 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'modules/tag/controllers') diff --git a/modules/tag/controllers/admin_tags.php b/modules/tag/controllers/admin_tags.php index 515b6891..19906c69 100644 --- a/modules/tag/controllers/admin_tags.php +++ b/modules/tag/controllers/admin_tags.php @@ -1,7 +1,7 @@ Date: Fri, 25 Jan 2013 08:47:29 +0100 Subject: #1956 - Escape LIKE queries (for _ and %). In MySQL queries, _ and % characters are treated as wildcards (similar to ? and *, respectively). - Added escape_for_like function to MY_Database.php - Added unit test to Database_Test - Corrected the five unescaped instances in the code using this function. --- modules/g2_import/controllers/g2.php | 2 +- modules/gallery/helpers/item_rest.php | 2 +- modules/gallery/libraries/MY_Database.php | 10 ++++++++++ modules/gallery/libraries/drivers/Cache/Database.php | 4 ++-- modules/gallery/tests/Database_Test.php | 6 ++++++ modules/tag/controllers/tags.php | 2 +- 6 files changed, 21 insertions(+), 5 deletions(-) (limited to 'modules/tag/controllers') diff --git a/modules/g2_import/controllers/g2.php b/modules/g2_import/controllers/g2.php index 5a76940e..0645266b 100644 --- a/modules/g2_import/controllers/g2.php +++ b/modules/g2_import/controllers/g2.php @@ -49,7 +49,7 @@ class G2_Controller extends Controller { if ($view == "core.DownloadItem") { $where[] = array("resource_type", "IN", array("file", "resize", "thumbnail", "full")); } else if ($view) { - $where[] = array("g2_url", "like", "%g2_view=$view%"); + $where[] = array("g2_url", "LIKE", "%" . Database::escape_for_like("g2_view=$view") . "%"); } // else: Assuming that the first search hit is sufficiently good. } else if ($path) { $where = array(array("g2_url", "IN", array($path, str_replace(" ", "+", $path)))); diff --git a/modules/gallery/helpers/item_rest.php b/modules/gallery/helpers/item_rest.php index 10799567..efeba2ef 100644 --- a/modules/gallery/helpers/item_rest.php +++ b/modules/gallery/helpers/item_rest.php @@ -64,7 +64,7 @@ class item_rest_Core { } if (isset($p->name)) { - $orm->where("name", "LIKE", "%{$p->name}%"); + $orm->where("name", "LIKE", "%" . Database::escape_for_like($p->name) . "%"); } if (isset($p->type)) { diff --git a/modules/gallery/libraries/MY_Database.php b/modules/gallery/libraries/MY_Database.php index aae0bb79..33759b67 100644 --- a/modules/gallery/libraries/MY_Database.php +++ b/modules/gallery/libraries/MY_Database.php @@ -88,4 +88,14 @@ abstract class Database extends Database_Core { static function set_default_instance($db) { self::$instances["default"] = $db; } + + /** + * Escape LIKE queries, add wildcards. In MySQL queries using LIKE, _ and % characters are + * treated as wildcards similar to ? and *, respectively. Therefore, we need to escape _, %, + * and \ (the escape character itself). + */ + static function escape_for_like($value) { + // backslash must go first to avoid double-escaping + return addcslashes($value, '\_%'); + } } \ No newline at end of file diff --git a/modules/gallery/libraries/drivers/Cache/Database.php b/modules/gallery/libraries/drivers/Cache/Database.php index a7aae92c..8790d0e1 100644 --- a/modules/gallery/libraries/drivers/Cache/Database.php +++ b/modules/gallery/libraries/drivers/Cache/Database.php @@ -69,7 +69,7 @@ class Cache_Database_Driver extends Cache_Driver { ->select() ->from("caches"); foreach ($tags as $tag) { - $db->where("tags", "LIKE", "%<$tag>%"); + $db->where("tags", "LIKE", "%" . Database::escape_for_like("<$tag>") . "%"); } $db_result = $db->execute(); @@ -139,7 +139,7 @@ class Cache_Database_Driver extends Cache_Driver { // Delete all caches } else if ($is_tag === true) { foreach ($keys as $tag) { - $db->where("tags", "LIKE", "%<$tag>%"); + $db->where("tags", "LIKE", "%" . Database::escape_for_like("<$tag>") . "%"); } } else { $db->where("key", "IN", $keys); diff --git a/modules/gallery/tests/Database_Test.php b/modules/gallery/tests/Database_Test.php index ab3290a9..106062f5 100644 --- a/modules/gallery/tests/Database_Test.php +++ b/modules/gallery/tests/Database_Test.php @@ -147,6 +147,12 @@ class Database_Test extends Gallery_Unit_Test_Case { $sql = str_replace("\n", " ", $sql); $this->assert_same("UPDATE [test_tables] SET [name] = [Test Name] WHERE [1] = [1]", $sql); } + + function escape_for_like_test() { + // Note: literal double backslash is written as \\\ + $this->assert_same('basic\_test', Database::escape_for_like("basic_test")); + $this->assert_same('\\\100\%\_test/', Database::escape_for_like('\100%_test/')); + } } class Database_Mock extends Database { diff --git a/modules/tag/controllers/tags.php b/modules/tag/controllers/tags.php index 77ad7f50..77d45a95 100644 --- a/modules/tag/controllers/tags.php +++ b/modules/tag/controllers/tags.php @@ -52,7 +52,7 @@ class Tags_Controller extends Controller { $limit = Input::instance()->get("limit"); $tag_part = ltrim(end($tag_parts)); $tag_list = ORM::factory("tag") - ->where("name", "LIKE", "{$tag_part}%") + ->where("name", "LIKE", Database::escape_for_like($tag_part) . "%") ->order_by("name", "ASC") ->limit($limit) ->find_all(); -- cgit v1.2.3 From 1e4d75c12072b49c3469f18af13bcf3439afc6b0 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Wed, 30 Jan 2013 12:10:18 -0500 Subject: Improve the display context API to return a "siblings_callback" field containing a callback that returns all the siblings. Fixes #1975. --- modules/gallery/controllers/albums.php | 6 ++++++ modules/search/controllers/search.php | 24 +++++++++++++----------- modules/tag/controllers/tag.php | 1 + 3 files changed, 20 insertions(+), 11 deletions(-) (limited to 'modules/tag/controllers') diff --git a/modules/gallery/controllers/albums.php b/modules/gallery/controllers/albums.php index e14fe347..d545b415 100644 --- a/modules/gallery/controllers/albums.php +++ b/modules/gallery/controllers/albums.php @@ -93,10 +93,16 @@ class Albums_Controller extends Items_Controller { "previous_item" => $previous_item, "next_item" => $next_item, "sibling_count" => $item->parent()->viewable()->children_count($where), + "siblings_callback" => array("Albums_Controller::get_siblings", array($item)), "parents" => $item->parents()->as_array(), "breadcrumbs" => Breadcrumb::array_from_item_parents($item)); } + static function get_siblings($item) { + // @todo consider creating Item_Model::siblings() if we use this more broadly. + return $item->parent()->viewable()->children(); + } + public function create($parent_id) { access::verify_csrf(); $album = ORM::factory("item", $parent_id); diff --git a/modules/search/controllers/search.php b/modules/search/controllers/search.php index f7f1d981..673a281f 100644 --- a/modules/search/controllers/search.php +++ b/modules/search/controllers/search.php @@ -54,8 +54,6 @@ class Search_Controller extends Controller { list ($count, $result) = search::search_within_album($q_with_more_terms, $album, $page_size, $offset); - $title = t("Search: %q", array("q" => $q_with_more_terms)); - $max_pages = max(ceil($count / $page_size), 1); $template = new Theme_View("page.html", "collection", "search"); @@ -77,28 +75,27 @@ class Search_Controller extends Controller { print $template; - item::set_display_context_callback( - "Search_Controller::get_display_context", $album->id, $title, $q_with_more_terms, $q); + item::set_display_context_callback("Search_Controller::get_display_context", $album, $q); } - static function get_display_context($item, $album_id, $title, $query_terms, $q) { - $album = ORM::factory("item", $album_id); - $position = search::get_position_within_album($item, $query_terms, $album); + static function get_display_context($item, $album, $q) { + $q_with_more_terms = search::add_query_terms($q); + $position = search::get_position_within_album($item, $q_with_more_terms, $album); if ($position > 1) { list ($count, $result_data) = - search::search_within_album($query_terms, $album, 3, $position - 2); + search::search_within_album($q_with_more_terms, $album, 3, $position - 2); list ($previous_item, $ignore, $next_item) = $result_data; } else { $previous_item = null; list ($count, $result_data) = - search::search_within_album($query_terms, $album, 1, $position); + search::search_within_album($q_with_more_terms, $album, 1, $position); list ($next_item) = $result_data; } $search_url = url::abs_site("search" . "?q=" . urlencode($q) . - "&album=" . urlencode($album_id) . + "&album=" . urlencode($album->id) . "&show={$item->id}"); $root = item::root(); @@ -106,9 +103,14 @@ class Search_Controller extends Controller { "previous_item" => $previous_item, "next_item" => $next_item, "sibling_count" => $count, + "siblings_callback" => array("Search_Controller::get_siblings", array($q, $album)), "breadcrumbs" => array( - Breadcrumb::instance($root->title, "/", $root->id)->set_first(), + Breadcrumb::instance($root->title, $root->url())->set_first(), Breadcrumb::instance(t("Search: %q", array("q" => $q)), $search_url), Breadcrumb::instance($item->title, $item->url())->set_last())); } + + static function get_siblings($q, $album) { + return search::search_within_album(search::add_query_terms($q), $album, 1000, 1)[1]; + } } diff --git a/modules/tag/controllers/tag.php b/modules/tag/controllers/tag.php index 6199c49b..bada9bac 100644 --- a/modules/tag/controllers/tag.php +++ b/modules/tag/controllers/tag.php @@ -86,6 +86,7 @@ class Tag_Controller extends Controller { "previous_item" => $previous_item, "next_item" => $next_item, "sibling_count" => $tag->items_count($where), + "siblings_callback" => array(array($tag, "items"), array()), "breadcrumbs" => array( Breadcrumb::instance($root->title, $root->url())->set_first(), Breadcrumb::instance(t("Tag: %tag_name", array("tag_name" => $tag->name)), -- cgit v1.2.3