public function test_type_supported_normalCase() { $this->t->is(\libraries\Image::type_supported('image/png'), true, 'image/png should be supported'); $this->t->is(\libraries\Image::type_supported('image/jpeg'), true, 'image/jpeg should be supported'); $this->t->is(\libraries\Image::type_supported('application/pdf'), true, 'application/pdf should be supported'); $this->t->is(\libraries\Image::type_supported('application/octet-stream'), false, 'application/octet-stream should not be supported'); $this->t->is(\libraries\Image::type_supported('text/plain'), false, 'text/plain should not be supported'); }
function _download() { $id = $this->uri->segment(1); $lexer = urldecode($this->uri->segment(2)); $is_multipaste = false; if ($this->mmultipaste->id_exists($id)) { $is_multipaste = true; if (!$this->mmultipaste->valid_id($id)) { return $this->_non_existent(); } $files = $this->mmultipaste->get_files($id); $this->data["title"] = $this->_multipaste_page_title($files); } elseif ($this->mfile->id_exists($id)) { if (!$this->mfile->valid_id($id)) { return $this->_non_existent(); } $files = array($this->mfile->get_filedata($id)); $this->data["title"] = htmlspecialchars($files[0]["filename"]); } else { assert(0); } assert($files !== false); assert(is_array($files)); assert(count($files) >= 1); // don't allow unowned files to be downloaded foreach ($files as $filedata) { if ($filedata["user"] == 0) { return $this->_non_existent(); } } $etag = ""; foreach ($files as $filedata) { $etag = sha1($etag . $filedata["data_id"]); } // handle some common "lexers" here switch ($lexer) { case "": break; case "qr": handle_etag($etag); header("Content-disposition: inline; filename=\"" . $id . "_qr.png\"\n"); header("Content-Type: image/png\n"); echo (new \libraries\ProcRunner(array('qrencode', '-s', '10', '-o', '-', site_url($id) . '/')))->execSafe()['stdout']; exit; case "info": return $this->_display_info($id); case "tar": if ($is_multipaste) { return $this->_tarball($id); } case "pls": if ($is_multipaste) { return $this->_generate_playlist($id); } default: if ($is_multipaste) { throw new \exceptions\UserInputException("file/download/invalid-action", "Invalid action \"" . htmlspecialchars($lexer) . "\""); } break; } $this->load->driver("ddownload"); // user wants the plain file if ($lexer == 'plain') { assert(count($files) == 1); handle_etag($etag); $filedata = $files[0]; $filepath = $this->mfile->file($filedata["data_id"]); $this->ddownload->serveFile($filepath, $filedata["filename"], "text/plain"); exit; } $this->load->library("output_cache"); foreach ($files as $key => $filedata) { $file = $this->mfile->file($filedata['data_id']); $pygments = new \libraries\Pygments($file, $filedata["mimetype"], $filedata["filename"]); // autodetect the lexer for highlighting if the URL contains a / after the ID (/ID/) // /ID/lexer disables autodetection $autodetect_lexer = !$lexer && substr_count(ltrim($this->uri->uri_string(), "/"), '/') >= 1; $autodetect_lexer = $is_multipaste ? true : $autodetect_lexer; if ($autodetect_lexer) { $lexer = $pygments->autodetect_lexer(); } // resolve aliases // this is mainly used for compatibility $lexer = $pygments->resolve_lexer_alias($lexer); // if there is no mimetype mapping we can't highlight it $can_highlight = $pygments->can_highlight(); $filesize_too_big = filesize($file) > $this->config->item('upload_max_text_size'); if (!$can_highlight || $filesize_too_big || !$lexer) { if (!$is_multipaste) { // prevent javascript from being executed and forbid frames // this should allow us to serve user submitted HTML content without huge security risks foreach (array("X-WebKit-CSP", "X-Content-Security-Policy", "Content-Security-Policy") as $header_name) { header("{$header_name}: default-src 'none'; img-src *; media-src *; font-src *; style-src 'unsafe-inline' *; script-src 'none'; object-src *; frame-src 'none'; "); } handle_etag($etag); $this->ddownload->serveFile($file, $filedata["filename"], $filedata["mimetype"]); exit; } else { $mimetype = $filedata["mimetype"]; $base = explode("/", $filedata["mimetype"])[0]; if (\libraries\Image::type_supported($mimetype)) { $filedata["tooltip"] = $this->_tooltip_for_image($filedata); $filedata["orientation"] = libraries\Image::get_exif_orientation($file); $this->output_cache->add_merge(array("items" => array($filedata)), 'file/fragments/thumbnail'); } else { if ($base == "audio") { $this->output_cache->add(array("filedata" => $filedata), "file/fragments/audio-player"); } else { if ($base == "video") { $this->output_cache->add(array("filedata" => $filedata), "file/fragments/video-player"); } else { $this->output_cache->add_merge(array("items" => array($filedata)), 'file/fragments/uploads_table'); } } } continue; } } $this->output_cache->add_function(function () use($filedata, $lexer, $is_multipaste) { $this->_highlight_file($filedata, $lexer, $is_multipaste); }); } // TODO: move lexers json to dedicated URL $this->data['lexers'] = \libraries\Pygments::get_lexers(); // Output everything // Don't use the output class/append_output because it does too // much magic ({elapsed_time} and {memory_usage}). // Direct echo puts us on the safe side. echo $this->load->view($this->var->view_dir . '/html_header', $this->data, true); $this->output_cache->render(); echo $this->load->view($this->var->view_dir . '/html_footer', $this->data, true); }