diff --git a/core/extension.class.php b/core/extension.class.php index a1175341..3407ba10 100644 --- a/core/extension.class.php +++ b/core/extension.class.php @@ -142,7 +142,7 @@ abstract class DataHandlerExtension extends Extension { public function onDataUpload(DataUploadEvent $event) { global $user; - if($this->supported_ext($event->type) && $this->check_contents($event->tmpname)) { + if(($supported_ext = $this->supported_ext($event->type)) && ($check_contents = $this->check_contents($event->tmpname))) { if(!move_upload_to_archive($event)) return; send_event(new ThumbnailGenerationEvent($event->hash, $event->type)); @@ -197,6 +197,9 @@ abstract class DataHandlerExtension extends Extension { } } } + elseif($supported_ext && !$check_contents){ + throw new UploadException("Invalid or corrupted file"); + } } public function onThumbnailGeneration(ThumbnailGenerationEvent $event) { diff --git a/core/imageboard.pack.php b/core/imageboard.pack.php index e36c40ee..6d5cd1cd 100644 --- a/core/imageboard.pack.php +++ b/core/imageboard.pack.php @@ -26,6 +26,7 @@ $tag_n = 0; // temp hack $_flexihash = null; $_fh_last_opts = null; +$order_sql = null; // this feels ugly require_once "lib/flexihash.php"; @@ -114,7 +115,7 @@ class Image { assert(is_numeric($start)); assert(is_numeric($limit)); assert(is_array($tags)); - global $database, $user; + global $database, $user, $config, $order_sql; $images = array(); @@ -128,13 +129,15 @@ class Image { } $querylet = Image::build_search_querylet($tags); - $querylet->append(new Querylet("ORDER BY images.id DESC LIMIT :limit OFFSET :offset", array("limit"=>$limit, "offset"=>$start))); + $querylet->append(new Querylet(" ORDER BY images.".($order_sql ?: $config->get_string("index_order")))); + $querylet->append(new Querylet(" LIMIT :limit OFFSET :offset", array("limit"=>$limit, "offset"=>$start))); #var_dump($querylet->sql); var_dump($querylet->variables); $result = $database->execute($querylet->sql, $querylet->variables); while($row = $result->fetch()) { $images[] = new Image($row); } + $order_sql = null; return $images; } @@ -476,6 +479,18 @@ class Image { $this->delete_tags_from_image(); // insert each new tags foreach($tags as $tag) { + if(preg_match("/^source[=|:](.*)$/i", $tag, $matches)) { + $this->set_source($matches[1]); + continue; + } + if(preg_match("/^pool[=|:](.*)$/i", $tag, $matches)) { + if(class_exists("Pools")) { + $pls = new Pools(); + $pls->add_post_from_tag($matches[1], $this->id); + } + continue; + } + $id = $database->get_one( $database->scoreql_to_sql( "SELECT id FROM tags WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(:tag)" @@ -651,6 +666,8 @@ class Image { } } + $terms = Tag::resolve_aliases($terms); + // parse the words that are searched for into // various types of querylet foreach($terms as $term) { @@ -663,8 +680,6 @@ class Image { continue; } - $term = Tag::resolve_alias($term); - $stpe = new SearchTermParseEvent($term, $terms); send_event($stpe); if($stpe->is_querylet_set()) { @@ -812,6 +827,8 @@ class Image { } } + $terms = Tag::resolve_aliases($terms); + reset($terms); // rewind to first element in array. // turn each term into a specific type of querylet @@ -821,8 +838,6 @@ class Image { $negative = true; $term = substr($term, 1); } - - $term = Tag::resolve_alias($term); $stpe = new SearchTermParseEvent($term, $terms); send_event($stpe); @@ -1070,11 +1085,22 @@ class Tag { assert(is_array($tags)); $new = array(); - foreach($tags as $tag) { - $new_set = explode(' ', Tag::resolve_alias($tag)); - foreach($new_set as $new_one) { - $new[] = $new_one; + + $i = 0; + $tag_count = count($tags); + while($i<$tag_count) { + $aliases = explode(' ', Tag::resolve_alias($tags[$i])); + foreach($aliases as $alias){ + if(!in_array($alias, $new)){ + if($tags[$i] == $alias){ + $new[] = $alias; + }elseif(!in_array($alias, $tags)){ + $tags[] = $alias; + $tag_count++; + } + } } + $i++; } $new = array_iunique($new); // remove any duplicate tags diff --git a/core/util.inc.php b/core/util.inc.php index b1331a4a..a4c5b244 100644 --- a/core/util.inc.php +++ b/core/util.inc.php @@ -509,14 +509,15 @@ function captcha_check() { * @param string &$file File path * @return string */ -function getMimeType($file, $ext="") { +function getMimeType($file, $ext="", $list=false) { // Static extension lookup $ext = strtolower($ext); static $exts = array( 'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png', 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'ico' => 'image/x-icon', - 'swf' => 'application/x-shockwave-flash', 'pdf' => 'application/pdf', + 'swf' => 'application/x-shockwave-flash', 'video/x-flv' => 'flv', + 'svg' => 'image/svg+xml', 'pdf' => 'application/pdf', 'zip' => 'application/zip', 'gz' => 'application/x-gzip', 'tar' => 'application/x-tar', 'bz' => 'application/x-bzip', 'bz2' => 'application/x-bzip2', 'txt' => 'text/plain', @@ -529,6 +530,8 @@ function getMimeType($file, $ext="") { 'mp4' => 'video/mp4', 'ogv' => 'video/ogg', 'webm' => 'video/webm' ); + if ($list == true){ return $exts; } + if (isset($exts[$ext])) { return $exts[$ext]; } $type = false; @@ -556,6 +559,17 @@ function getMimeType($file, $ext="") { return 'application/octet-stream'; } + +function getExtension ($mime_type){ + if(empty($mime_type)){ + return false; + } + + $extensions = getMimeType(null, null, true); + $ext = array_search($mime_type, $extensions); + return ($ext ?: false); +} + /** * @private */ @@ -801,17 +815,24 @@ function transload($url, $mfile) { $ch = curl_init($url); $fp = fopen($mfile, "w"); - curl_setopt($ch, CURLOPT_FILE, $fp); - curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_VERBOSE, 1); + curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_REFERER, $url); curl_setopt($ch, CURLOPT_USERAGENT, "Shimmie-".VERSION); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); - curl_exec($ch); + $response = curl_exec($ch); + + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); + $headers = http_parse_headers(implode("\n", preg_split('/\R/', rtrim(substr($response, 0, $header_size))))); + $body = substr($response, $header_size); + curl_close($ch); + fwrite($fp, $body); fclose($fp); - return true; + return $headers; } if($config->get_string("transload_engine") === "wget") { @@ -839,12 +860,36 @@ function transload($url, $mfile) { fwrite($fp, $data); fclose($fp); - return true; + $headers = http_parse_headers(implode("\n", $http_response_header)); + + return $headers; } return false; } +if (!function_exists('http_parse_headers')) { #http://www.php.net/manual/en/function.http-parse-headers.php#112917 + function http_parse_headers ($raw_headers){ + $headers = array(); // $headers = []; + + foreach (explode("\n", $raw_headers) as $i => $h) { + $h = explode(':', $h, 2); + + if (isset($h[1])){ + if(!isset($headers[$h[0]])){ + $headers[$h[0]] = trim($h[1]); + }else if(is_array($headers[$h[0]])){ + $tmp = array_merge($headers[$h[0]],array(trim($h[1]))); + $headers[$h[0]] = $tmp; + }else{ + $tmp = array_merge(array($headers[$h[0]]),array(trim($h[1]))); + $headers[$h[0]] = $tmp; + } + } + } + return $headers; + } +} $_included = array(); /** diff --git a/ext/artists/main.php b/ext/artists/main.php index d426d512..984b12af 100644 --- a/ext/artists/main.php +++ b/ext/artists/main.php @@ -45,7 +45,7 @@ class Artists extends Extension { public function onSearchTermParse(SearchTermParseEvent $event) { $matches = array(); - if(preg_match("/^author=(.*)$/", $event->term, $matches)) { + if(preg_match("/^author[=|:](.*)$/", $event->term, $matches)) { $char = $matches[1]; $event->add_querylet(new Querylet("Author = :author_char", array("author_char"=>$char))); } diff --git a/ext/comment/main.php b/ext/comment/main.php index 22bf4551..1c472626 100644 --- a/ext/comment/main.php +++ b/ext/comment/main.php @@ -262,12 +262,12 @@ class CommentList extends Extension { public function onSearchTermParse(SearchTermParseEvent $event) { $matches = array(); - if(preg_match("/comments(<|>|<=|>=|=)(\d+)/", $event->term, $matches)) { - $cmp = $matches[1]; + if(preg_match("/^comments([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)$/", $event->term, $matches)) { + $cmp = ltrim($matches[1], ":") ?: "="; $comments = $matches[2]; $event->add_querylet(new Querylet("images.id IN (SELECT DISTINCT image_id FROM comments GROUP BY image_id HAVING count(image_id) $cmp $comments)")); } - else if(preg_match("/commented_by=(.*)/i", $event->term, $matches)) { + else if(preg_match("/^commented_by[=|:](.*)$/i", $event->term, $matches)) { global $database; $user = User::by_name($matches[1]); if(!is_null($user)) { @@ -279,7 +279,7 @@ class CommentList extends Extension { $event->add_querylet(new Querylet("images.id IN (SELECT image_id FROM comments WHERE owner_id = $user_id)")); } - else if(preg_match("/commented_by_userid=([0-9]+)/i", $event->term, $matches)) { + else if(preg_match("/^commented_by_userno[=|:]([0-9]+)$/i", $event->term, $matches)) { $user_id = int_escape($matches[1]); $event->add_querylet(new Querylet("images.id IN (SELECT image_id FROM comments WHERE owner_id = $user_id)")); } @@ -293,6 +293,8 @@ class CommentList extends Extension { $user_ratings = Ratings::get_user_privs($user); } + $where = SPEED_HAX ? "WHERE posted > now() - interval '24 hours'" : ""; + $total_pages = $database->cache->get("comment_pages"); if(empty($total_pages)) { $total_pages = (int)($database->get_one("SELECT COUNT(c1) FROM (SELECT COUNT(image_id) AS c1 FROM comments $where GROUP BY image_id) AS s1") / 10); @@ -307,7 +309,6 @@ class CommentList extends Extension { $threads_per_page = 10; $start = $threads_per_page * ($current_page - 1); - $where = SPEED_HAX ? "WHERE posted > now() - interval '24 hours'" : ""; $get_threads = " SELECT image_id,MAX(posted) AS latest FROM comments $where @@ -320,13 +321,15 @@ class CommentList extends Extension { $images = array(); while($row = $result->fetch()) { $image = Image::by_id($row["image_id"]); - $comments = $this->get_comments($image->id); - if(class_exists("Ratings")) { - if(strpos($user_ratings, $image->rating) === FALSE) { - $image = null; // this is "clever", I may live to regret it + if (!is_null($image)) { + $comments = $this->get_comments($image->id); + if(class_exists("Ratings")) { + if(strpos($user_ratings, $image->rating) === FALSE) { + $image = null; // this is "clever", I may live to regret it + } } + if(!is_null($image)) $images[] = array($image, $comments); } - if(!is_null($image)) $images[] = array($image, $comments); } $this->theme->display_comment_list($images, $current_page, $total_pages, $user->can("create_comment")); @@ -335,8 +338,7 @@ class CommentList extends Extension { // get comments {{{ private function get_recent_comments($count) { - global $config; - global $database; + global $config, $database; $rows = $database->get_all(" SELECT users.id as user_id, users.name as user_name, users.email as user_email, users.class as user_class, @@ -356,8 +358,7 @@ class CommentList extends Extension { } private function get_user_comments(/*int*/ $user_id, /*int*/ $count, /*int*/ $offset=0) { - global $config; - global $database; + global $config, $database; $rows = $database->get_all(" SELECT users.id as user_id, users.name as user_name, users.email as user_email, users.class as user_class, @@ -378,8 +379,7 @@ class CommentList extends Extension { } private function get_comments(/*int*/ $image_id) { - global $config; - global $database; + global $config, $database; $i_image_id = int_escape($image_id); $rows = $database->get_all(" SELECT @@ -402,9 +402,7 @@ class CommentList extends Extension { // add / remove / edit comments {{{ private function is_comment_limit_hit() { - global $user; - global $config; - global $database; + global $user, $config, $database; // sqlite fails at intervals if($database->get_driver_name() === "sqlite") return false; @@ -493,9 +491,9 @@ class CommentList extends Extension { } return $pagenum; } + private function add_comment_wrapper(/*int*/ $image_id, User $user, /*string*/ $comment) { - global $database; - global $config; + global $database, $config; // basic sanity checks if(!$user->can("create_comment")) { diff --git a/ext/danbooru_api/main.php b/ext/danbooru_api/main.php index f5d8773e..2ba1b82d 100644 --- a/ext/danbooru_api/main.php +++ b/ext/danbooru_api/main.php @@ -54,14 +54,6 @@ class DanbooruApi extends Extension { } } - public function onSearchTermParse(SearchTermParseEvent $event) { - $matches = array(); - if(preg_match("/^md5:([0-9a-fA-F]*)$/i", $event->term, $matches)) { - $hash = strtolower($matches[1]); - $event->add_querylet(new Querylet("images.hash = '$hash'")); // :-O - } - } - // Danbooru API private function api_danbooru(PageRequestEvent $event) { diff --git a/ext/favorites/main.php b/ext/favorites/main.php index aee35d6a..6517377e 100644 --- a/ext/favorites/main.php +++ b/ext/favorites/main.php @@ -117,12 +117,12 @@ class Favorites extends Extension { public function onSearchTermParse(SearchTermParseEvent $event) { $matches = array(); - if(preg_match("/favorites(<|>|<=|>=|=)(\d+)/", $event->term, $matches)) { - $cmp = $matches[1]; + if(preg_match("/^favorites([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)$/", $event->term, $matches)) { + $cmp = ltrim($matches[1], ":") ?: "="; $favorites = $matches[2]; $event->add_querylet(new Querylet("images.id IN (SELECT id FROM images WHERE favorites $cmp $favorites)")); } - else if(preg_match("/favorited_by=(.*)/i", $event->term, $matches)) { + else if(preg_match("/^favorited_by[=|:](.*)$/i", $event->term, $matches)) { global $database; $user = User::by_name($matches[1]); if(!is_null($user)) { @@ -134,7 +134,7 @@ class Favorites extends Extension { $event->add_querylet(new Querylet("images.id IN (SELECT image_id FROM user_favorites WHERE user_id = $user_id)")); } - else if(preg_match("/favorited_by_userno=([0-9]+)/i", $event->term, $matches)) { + else if(preg_match("/^favorited_by_userno[=|:](\d+)$/i", $event->term, $matches)) { $user_id = int_escape($matches[1]); $event->add_querylet(new Querylet("images.id IN (SELECT image_id FROM user_favorites WHERE user_id = $user_id)")); } diff --git a/ext/handle_pixel/theme.php b/ext/handle_pixel/theme.php index 4099e97f..74f9af4c 100644 --- a/ext/handle_pixel/theme.php +++ b/ext/handle_pixel/theme.php @@ -13,6 +13,10 @@ class PixelFileHandlerTheme extends Themelet { foreach ($exif as $key => $section) { foreach ($section as $name => $val) { if($key == "IFD0") { + // Cheap fix for array'd values in EXIF-data + if (is_array($val)) { + $val = implode(',', $val); + } $head .= html_escape("$name: $val")."
\n"; } } diff --git a/ext/index/main.php b/ext/index/main.php index f851bde7..9cf5abfc 100644 --- a/ext/index/main.php +++ b/ext/index/main.php @@ -21,6 +21,16 @@ *
  • size>=500x500 -- no small images *
  • size<1000x1000 -- no large images * + *
  • width (=, <, >, <=, >=) width, eg + * + *
  • height (=, <, >, <=, >=) height, eg + * *
  • ratio (=, <, >, <=, >=) width : height, eg * - *
  • user=Username, eg + *
  • user=Username & poster=Username, eg * - *
  • hash=md5sum, eg + *
  • user_id=userID & poster_id=userID, eg + * + *
  • hash=md5sum & md5=md5sum, eg * - *
  • filetype=type, eg + *
  • filetype=type & ext=type, eg * - *
  • filename=blah, eg + *
  • filename=blah & name=blah, eg * *
  • posted (=, <, >, <=, >=) date, eg * + *
  • tags (=, <, >, <=, >=) count, eg + * + *
  • source=(URL, any, none) eg + * + *
  • order=(id, width, height, filesize, filename)_(ASC, DESC), eg + * * *

    Search items can be combined to search for images which match both, * or you can stick "-" in front of an item to search for things that don't * match it. + *

    Metatags can be followed by ":" rather than "=" if you prefer. + *
    I.E: "posted:2014-01-01", "id:>=500" etc. *

    Some search methods provided by extensions: *