<commit_before><?
// The source code packaged with this file is Free Software, Copyright (C) 2010 by
// <NAME> <gallir at uib dot es>.
// It's licensed under the AFFERO GENERAL PUBLIC LICENSE unless stated otherwise.
// You can get copies of the licenses here:
//		http://www.affero.org/oagpl.html
// AFFERO GENERAL PUBLIC LICENSE is also included in the file called "COPYING".


class Upload {
	static function get_cache_relative_dir($key = false) {
		global $globals;

		return $globals['cache_dir'].sprintf("/%02x/%02x", ($key >> 16) & 255, ($key >> 8) & 255);
	}

	static function get_cache_dir($key = false) {
		global $globals;

		// Very fast cache dir generator for two levels
		// mask == 2^8 - 1 or 1 << 8 -1
		if (! $key) {
			return mnmpath.'/'.$globals['cache_dir'];
		} else {
			return mnmpath. '/' . Upload::get_cache_relative_dir($key);
		}
	}

	static function create_cache_dir($key = false) {
		global $globals;

		if (file_exists(Upload::get_cache_dir($key))) return true;
		$dir = Upload::get_cache_dir($key);
		syslog(LOG_INFO, "Meneame, creating cache dir " . $dir);
		$old_mask = umask(0);
		$res = @mkdir($dir, 0777, true);
		umask($old_mask);
		return $res;
	}

	static function current_user_limit_exceded($file) {
		global $current_user, $globals;

		// Check current_user file upload limits
		if ($file['size'] > $globals['media_max_size']) return _('tamaño excedido');
		if ($current_user->user_karma < $globals['media_min_karma']) return _('karma bajo');
		if (Upload::user_uploads($current_user->user_id, 24) > $globals['media_max_upload_per_day']) return _('máximas subidas diarias excedidas');
		if (Upload::user_bytes_uploaded($current_user->user_id, 24) > $globals['media_max_bytes_per_day'] * 1.2) return _('máximos bytes por día excedidos');
		return false;
	}


	static function user_bytes_uploaded($user, $hours = false) {
		global $db;

		if (! $user > 0) return 0;
		if ($hours) $date_limit = "and date > date_sub(now(), interval $hours hour)";
		else $date_limit = '';

		return intval($db->get_var("select sum(size) from media where user = $user $date_limit"));
	}

	static function user_uploads($user, $hours = false) {
		global $db;

		if (! $user > 0) return 0;
		if ($hours) $date_limit = "and date > date_sub(now(), interval $hours hour)";
		else $date_limit = '';

		return intval($db->get_var("select count(*) from media where user = $user $date_limit"));
	}

	function __construct($type, $id, $version = 0, $time = false) {
		global $globals;

		$this->type = $type;
		$this->id = $id;
		$this->to = 0;
		$this->access = 'restricted';
		$this->version = $version;
		if (! $time ) {
			$this->date = $globals['now'];
		} else {
			$this->date = $time;
		}
		$this->dim1 = $this->dim2 = 0;
	}

	function store() {
		global $db, $current_user, $globals;

		if (! $this->user) $this->user = $current_user->user_id;

		$mime = $db->escape($this->mime);
		$access = $db->escape($this->access);
		$db->query("REPLACE INTO media (type, id, version, user, `to`, access, mime, size, date, dim1, dim2) VALUES ('$this->type', $this->id, $this->version, $this->user, $this->to, '$access', '$mime', $this->size, FROM_UNIXTIME($this->date), $this->dim1, $this->dim2)");
		$this->backup();
		return true;
	}

	function read() {
		global $db, $current_user;

		if(($result = $db->get_row("SELECT type, id, version, user, `to`, access, mime, size, UNIX_TIMESTAMP(date) as date, dim1, dim2 FROM media WHERE type = '$this->type' and id = $this->id and version = $this->version"))) {
			foreach(get_object_vars($result) as $var => $value) $this->$var = $value;
			$this->read = true;
			return true;
		}
		$this->read = false;
		return false;
	}

	function delete() {
		global $db, $globals;

		$this->clean();
		$this->delete_backup();
		$db->query("delete from media where type = '$this->type' and id = $this->id and version = $this->version");
	}

	function clean() {
		@unlink($this->pathname());
	}

	function from_temporal($file, $type = false) {
		global $current_user, $globals;

		// Check __again__ the limits
		Upload::current_user_limit_exceded($file);

		if ($type && ! preg_match("/$type/", $file['type'])) return false;
		$this->mime = $file['type'];
		$this->size = $file['size'];
		$this->user = $current_user->user_id;
		Upload::create_cache_dir($this->id);
		if (move_uploaded_file($file['tmp_name'], $this->pathname())) {
			return $this->store();
		} else {
			syslog(LOG_INFO, "Meneame, error moving to " . $this->pathname());
		}
		return false;
	}

	function filename() {
		return sprintf("%s-%d-%d-%d.media", $this->type, $this->user, $this->id, $this->version);
	}

	function pathname() {
		return Upload::get_cache_dir($this->id).'/'.$this->filename();
	}

	function url() {
		global $globals;

		return $globals['base_url'].Upload::get_cache_relative_dir($this->id).'/'.$this->filename();
	}

	function readfile() {
		if (! file_exists($this->pathname())) {
			$this->restore();
		}
		return readfile($this->pathname());
	}


	// Call S3 functions
	function backup() {
		global $globals;

		if ($globals['Amazon_S3_media_bucket'] && $globals['Amazon_S3_upload']) {
			return Media::put($this->pathname(), $this->type);
		}
		return true;
	}

	function restore() {
		global $globals;

		if ($globals['Amazon_S3_media_bucket']) {
			Upload::create_cache_dir($this->id);
			return Media::get($this->filename(), $this->type, $this->pathname());
		}
	}

	function delete_backup() {
		global $globals;

		if ($globals['Amazon_S3_media_bucket']) {
			return Media::rm($this->type.'/'.$this->filename());
		}
	}
}

?>
<commit_msg>Security: check strict form image type (^image)<commit_after><?
// The source code packaged with this file is Free Software, Copyright (C) 2010 by
// <NAME> <gallir at uib dot es>.
// It's licensed under the AFFERO GENERAL PUBLIC LICENSE unless stated otherwise.
// You can get copies of the licenses here:
//		http://www.affero.org/oagpl.html
// AFFERO GENERAL PUBLIC LICENSE is also included in the file called "COPYING".


class Upload {
	static function get_cache_relative_dir($key = false) {
		global $globals;

		return $globals['cache_dir'].sprintf("/%02x/%02x", ($key >> 16) & 255, ($key >> 8) & 255);
	}

	static function get_cache_dir($key = false) {
		global $globals;

		// Very fast cache dir generator for two levels
		// mask == 2^8 - 1 or 1 << 8 -1
		if (! $key) {
			return mnmpath.'/'.$globals['cache_dir'];
		} else {
			return mnmpath. '/' . Upload::get_cache_relative_dir($key);
		}
	}

	static function create_cache_dir($key = false) {
		global $globals;

		if (file_exists(Upload::get_cache_dir($key))) return true;
		$dir = Upload::get_cache_dir($key);
		syslog(LOG_INFO, "Meneame, creating cache dir " . $dir);
		$old_mask = umask(0);
		$res = @mkdir($dir, 0777, true);
		umask($old_mask);
		return $res;
	}

	static function current_user_limit_exceded($file) {
		global $current_user, $globals;

		// Check current_user file upload limits
		if ($file['size'] > $globals['media_max_size']) return _('tamaño excedido');
		if ($current_user->user_karma < $globals['media_min_karma']) return _('karma bajo');
		if (Upload::user_uploads($current_user->user_id, 24) > $globals['media_max_upload_per_day']) return _('máximas subidas diarias excedidas');
		if (Upload::user_bytes_uploaded($current_user->user_id, 24) > $globals['media_max_bytes_per_day'] * 1.2) return _('máximos bytes por día excedidos');
		return false;
	}


	static function user_bytes_uploaded($user, $hours = false) {
		global $db;

		if (! $user > 0) return 0;
		if ($hours) $date_limit = "and date > date_sub(now(), interval $hours hour)";
		else $date_limit = '';

		return intval($db->get_var("select sum(size) from media where user = $user $date_limit"));
	}

	static function user_uploads($user, $hours = false) {
		global $db;

		if (! $user > 0) return 0;
		if ($hours) $date_limit = "and date > date_sub(now(), interval $hours hour)";
		else $date_limit = '';

		return intval($db->get_var("select count(*) from media where user = $user $date_limit"));
	}

	function __construct($type, $id, $version = 0, $time = false) {
		global $globals;

		$this->type = $type;
		$this->id = $id;
		$this->to = 0;
		$this->access = 'restricted';
		$this->version = $version;
		if (! $time ) {
			$this->date = $globals['now'];
		} else {
			$this->date = $time;
		}
		$this->dim1 = $this->dim2 = 0;
	}

	function store() {
		global $db, $current_user, $globals;

		if (! $this->user) $this->user = $current_user->user_id;

		$mime = $db->escape($this->mime);
		$access = $db->escape($this->access);
		$db->query("REPLACE INTO media (type, id, version, user, `to`, access, mime, size, date, dim1, dim2) VALUES ('$this->type', $this->id, $this->version, $this->user, $this->to, '$access', '$mime', $this->size, FROM_UNIXTIME($this->date), $this->dim1, $this->dim2)");
		$this->backup();
		return true;
	}

	function read() {
		global $db, $current_user;

		if(($result = $db->get_row("SELECT type, id, version, user, `to`, access, mime, size, UNIX_TIMESTAMP(date) as date, dim1, dim2 FROM media WHERE type = '$this->type' and id = $this->id and version = $this->version"))) {
			foreach(get_object_vars($result) as $var => $value) $this->$var = $value;
			$this->read = true;
			return true;
		}
		$this->read = false;
		return false;
	}

	function delete() {
		global $db, $globals;

		$this->clean();
		$this->delete_backup();
		$db->query("delete from media where type = '$this->type' and id = $this->id and version = $this->version");
	}

	function clean() {
		@unlink($this->pathname());
	}

	function from_temporal($file, $type = false) {
		global $current_user, $globals;

		// Check __again__ the limits
		Upload::current_user_limit_exceded($file);

		if ($type && ! preg_match("/^$type/", $file['type'])) return false;
		$this->mime = $file['type'];
		$this->size = $file['size'];
		$this->user = $current_user->user_id;
		Upload::create_cache_dir($this->id);
		if (move_uploaded_file($file['tmp_name'], $this->pathname())) {
			return $this->store();
		} else {
			syslog(LOG_INFO, "Meneame, error moving to " . $this->pathname());
		}
		return false;
	}

	function filename() {
		return sprintf("%s-%d-%d-%d.media", $this->type, $this->user, $this->id, $this->version);
	}

	function pathname() {
		return Upload::get_cache_dir($this->id).'/'.$this->filename();
	}

	function url() {
		global $globals;

		return $globals['base_url'].Upload::get_cache_relative_dir($this->id).'/'.$this->filename();
	}

	function readfile() {
		if (! file_exists($this->pathname())) {
			$this->restore();
		}
		return readfile($this->pathname());
	}


	// Call S3 functions
	function backup() {
		global $globals;

		if ($globals['Amazon_S3_media_bucket'] && $globals['Amazon_S3_upload']) {
			return Media::put($this->pathname(), $this->type);
		}
		return true;
	}

	function restore() {
		global $globals;

		if ($globals['Amazon_S3_media_bucket']) {
			Upload::create_cache_dir($this->id);
			return Media::get($this->filename(), $this->type, $this->pathname());
		}
	}

	function delete_backup() {
		global $globals;

		if ($globals['Amazon_S3_media_bucket']) {
			return Media::rm($this->type.'/'.$this->filename());
		}
	}
}

?>

{'fraction_non_alphanumeric': 0.18928092898615453, 'fraction_numerical': 0.00964716391246092, 'mean_word_length': 4.273669335845502, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 179, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '233131', 'n_tokens_mistral': 4422, 'n_tokens_neox': 3984, 'n_words': 948}