From 9d949e0e5c509fc43dd5d9df38ee4db8832fcae3 Mon Sep 17 00:00:00 2001 From: Uncled1023 Date: Sun, 21 Sep 2014 22:07:26 -0700 Subject: [PATCH] Updated GitList to 0.5 --- git/src/GitList/Application.php | 48 +++++++++++++++++++----- git/src/GitList/Controller/BlobController.php | 2 + git/src/GitList/Controller/CommitController.php | 20 +++++++++- git/src/GitList/Controller/MainController.php | 2 + git/src/GitList/Controller/NetworkController.php | 8 ++-- git/src/GitList/Controller/TreeController.php | 19 ++++------ git/src/GitList/Escaper/ArgumentEscaper.php | 15 ++++++++ git/src/GitList/Git/Client.php | 7 +++- git/src/GitList/Git/Repository.php | 7 ++-- git/src/GitList/Util/Repository.php | 3 ++ git/src/GitList/Util/Routing.php | 29 ++++++++------ 11 files changed, 118 insertions(+), 42 deletions(-) create mode 100755 git/src/GitList/Escaper/ArgumentEscaper.php diff --git a/git/src/GitList/Application.php b/git/src/GitList/Application.php index 0c658e65..18cc6815 100755 --- a/git/src/GitList/Application.php +++ b/git/src/GitList/Application.php @@ -9,6 +9,7 @@ use GitList\Provider\GitServiceProvider; use GitList\Provider\RepositoryUtilServiceProvider; use GitList\Provider\ViewUtilServiceProvider; use GitList\Provider\RoutingUtilServiceProvider; +use Symfony\Component\Filesystem\Filesystem; /** * GitList application. @@ -30,14 +31,15 @@ class Application extends SilexApplication $this->path = realpath($root); $this['debug'] = $config->get('app', 'debug'); + $this['date.format'] = $config->get('date', 'format') ? $config->get('date', 'format') : 'd/m/Y H:i:s'; + $this['theme'] = $config->get('app', 'theme') ? $config->get('app', 'theme') : 'default'; $this['filetypes'] = $config->getSection('filetypes'); + $this['binary_filetypes'] = $config->getSection('binary_filetypes'); $this['cache.archives'] = $this->getCachePath() . 'archives'; - $this['path_prefix'] = $config->get('app', 'path_prefix'); - $this['clone_url'] = $config->get('app', 'clone_url'); // Register services $this->register(new TwigServiceProvider(), array( - 'twig.path' => $this->getViewPath(), + 'twig.path' => array($this->getThemePath($this['theme']), $this->getThemePath('default')), 'twig.options' => $config->get('app', 'cache') ? array('cache' => $this->getCachePath() . 'views') : array(), )); @@ -60,12 +62,17 @@ class Application extends SilexApplication $this->register(new RoutingUtilServiceProvider()); $this['twig'] = $this->share($this->extend('twig', function ($twig, $app) { - $twig->addFilter('htmlentities', new \Twig_Filter_Function('htmlentities')); - $twig->addFilter('md5', new \Twig_Filter_Function('md5')); + $twig->addFilter(new \Twig_SimpleFilter('htmlentities', 'htmlentities')); + $twig->addFilter(new \Twig_SimpleFilter('md5', 'md5')); + $twig->addFilter(new \Twig_SimpleFilter('format_date', array($app, 'formatDate'))); return $twig; })); + $this['escaper.argument'] = $this->share(function() { + return new Escaper\ArgumentEscaper(); + }); + // Handle errors $this->error(function (\Exception $e, $code) use ($app) { if ($app['debug']) { @@ -76,26 +83,49 @@ class Application extends SilexApplication 'message' => $e->getMessage(), )); }); + + $this->finish(function () use ($app, $config) { + if (!$config->get('app', 'cache')) { + $fs = new Filesystem(); + $fs->remove($app['cache.archives']); + } + }); + } + + public function formatDate($date) + { + return $date->format($this['date.format']); } public function getPath() { return $this->path . DIRECTORY_SEPARATOR; } - + public function setPath($path) { $this->path = $path; + return $this; } public function getCachePath() { - return $this->path . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR; + return $this->path + . DIRECTORY_SEPARATOR + . 'cache' + . DIRECTORY_SEPARATOR; } - public function getViewPath() + public function getThemePath($theme) { - return $this->path . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR; + return $this->path + . DIRECTORY_SEPARATOR + . 'themes' + . DIRECTORY_SEPARATOR + . $theme + . DIRECTORY_SEPARATOR + . 'twig' + . DIRECTORY_SEPARATOR; } } diff --git a/git/src/GitList/Controller/BlobController.php b/git/src/GitList/Controller/BlobController.php index fc5ec907..86cef8bd 100755 --- a/git/src/GitList/Controller/BlobController.php +++ b/git/src/GitList/Controller/BlobController.php @@ -43,6 +43,7 @@ class BlobController implements ControllerProviderInterface )); })->assert('repo', $app['util.routing']->getRepositoryRegex()) ->assert('commitishPath', '.+') + ->convert('commitishPath', 'escaper.argument:escape') ->bind('blob'); $route->get('{repo}/raw/{commitishPath}', function ($repo, $commitishPath) use ($app) { @@ -66,6 +67,7 @@ class BlobController implements ControllerProviderInterface return new Response($blob, 200, $headers); })->assert('repo', $app['util.routing']->getRepositoryRegex()) ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) + ->convert('commitishPath', 'escaper.argument:escape') ->bind('blob_raw'); return $route; diff --git a/git/src/GitList/Controller/CommitController.php b/git/src/GitList/Controller/CommitController.php index 86dc4093..292e94c7 100755 --- a/git/src/GitList/Controller/CommitController.php +++ b/git/src/GitList/Controller/CommitController.php @@ -12,6 +12,15 @@ class CommitController implements ControllerProviderInterface { $route = $app['controllers_factory']; + $route->get('{repo}/commits/search', function (Request $request, $repo) use ($app) { + $subRequest = Request::create( + '/' . $repo . '/commits/master/search', + 'POST', + array('query' => $request->get('query')) + ); + return $app->handle($subRequest, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST); + })->assert('repo', $app['util.routing']->getRepositoryRegex()); + $route->get('{repo}/commits/{commitishPath}', function ($repo, $commitishPath) use ($app) { $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); @@ -31,10 +40,12 @@ class CommitController implements ControllerProviderInterface foreach ($commits as $commit) { $date = $commit->getDate(); - $date = $date->format('m/d/Y'); + $date = $date->format('Y-m-d'); $categorized[$date][] = $commit; } + krsort($categorized); + $template = $app['request']->isXmlHttpRequest() ? 'commits_list.twig' : 'commits.twig'; return $app['twig']->render($template, array( @@ -50,6 +61,7 @@ class CommitController implements ControllerProviderInterface })->assert('repo', $app['util.routing']->getRepositoryRegex()) ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) ->value('commitishPath', null) + ->convert('commitishPath', 'escaper.argument:escape') ->bind('commits'); $route->post('{repo}/commits/{branch}/search', function (Request $request, $repo, $branch = '') use ($app) { @@ -61,10 +73,12 @@ class CommitController implements ControllerProviderInterface foreach ($commits as $commit) { $date = $commit->getDate(); - $date = $date->format('m/d/Y'); + $date = $date->format('Y-m-d'); $categorized[$date][] = $commit; } + krsort($categorized); + return $app['twig']->render('searchcommits.twig', array( 'repo' => $repo, 'branch' => $branch, @@ -76,6 +90,7 @@ class CommitController implements ControllerProviderInterface )); })->assert('repo', $app['util.routing']->getRepositoryRegex()) ->assert('branch', $app['util.routing']->getBranchRegex()) + ->convert('branch', 'escaper.argument:escape') ->bind('searchcommits'); $route->get('{repo}/commit/{commit}', function ($repo, $commit) use ($app) { @@ -112,6 +127,7 @@ class CommitController implements ControllerProviderInterface )); })->assert('repo', $app['util.routing']->getRepositoryRegex()) ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) + ->convert('commitishPath', 'escaper.argument:escape') ->bind('blame'); return $route; diff --git a/git/src/GitList/Controller/MainController.php b/git/src/GitList/Controller/MainController.php index 3c8919cf..92de6aef 100755 --- a/git/src/GitList/Controller/MainController.php +++ b/git/src/GitList/Controller/MainController.php @@ -48,6 +48,7 @@ class MainController implements ControllerProviderInterface })->assert('repo', $app['util.routing']->getRepositoryRegex()) ->assert('branch', $app['util.routing']->getBranchRegex()) ->value('branch', null) + ->convert('branch', 'escaper.argument:escape') ->bind('stats'); $route->get('{repo}/{branch}/rss/', function($repo, $branch) use ($app) { @@ -69,6 +70,7 @@ class MainController implements ControllerProviderInterface })->assert('repo', $app['util.routing']->getRepositoryRegex()) ->assert('branch', $app['util.routing']->getBranchRegex()) ->value('branch', null) + ->convert('branch', 'escaper.argument:escape') ->bind('rss'); return $route; diff --git a/git/src/GitList/Controller/NetworkController.php b/git/src/GitList/Controller/NetworkController.php index 2814e9c5..1c6a9208 100755 --- a/git/src/GitList/Controller/NetworkController.php +++ b/git/src/GitList/Controller/NetworkController.php @@ -55,7 +55,7 @@ class NetworkController implements ControllerProviderInterface } $nextPageUrl = null; - + if ($pager['last'] !== $pager['current']) { $nextPageUrl = $app['url_generator']->generate( 'networkData', @@ -66,10 +66,10 @@ class NetworkController implements ControllerProviderInterface ) ); } - + // when no commits are given, return an empty response - issue #369 if( count($commits) === 0 ) { - return $app->json( array( + return $app->json( array( 'repo' => $repo, 'commitishPath' => $commitishPath, 'nextPage' => null, @@ -91,6 +91,7 @@ class NetworkController implements ControllerProviderInterface )->assert('repo', $app['util.routing']->getRepositoryRegex()) ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) ->value('commitishPath', null) + ->convert('commitishPath', 'escaper.argument:escape') ->assert('page', '\d+') ->value('page', '0') ->bind('networkData'); @@ -119,6 +120,7 @@ class NetworkController implements ControllerProviderInterface )->assert('repo', $app['util.routing']->getRepositoryRegex()) ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) ->value('commitishPath', null) + ->convert('commitishPath', 'escaper.argument:escape') ->bind('network'); return $route; diff --git a/git/src/GitList/Controller/TreeController.php b/git/src/GitList/Controller/TreeController.php index 384b5378..b3d88b43 100755 --- a/git/src/GitList/Controller/TreeController.php +++ b/git/src/GitList/Controller/TreeController.php @@ -4,8 +4,8 @@ namespace GitList\Controller; use Silex\Application; use Silex\ControllerProviderInterface; -use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\BinaryFileResponse; class TreeController implements ControllerProviderInterface { @@ -45,6 +45,7 @@ class TreeController implements ControllerProviderInterface )); })->assert('repo', $app['util.routing']->getRepositoryRegex()) ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) + ->convert('commitishPath', 'escaper.argument:escape') ->bind('tree'); $route->post('{repo}/tree/{branch}/search', function (Request $request, $repo, $branch = '', $tree = '') use ($app) { @@ -65,14 +66,13 @@ class TreeController implements ControllerProviderInterface 'breadcrumbs' => $breadcrumbs, 'branches' => $repository->getBranches(), 'tags' => $repository->getTags(), + 'query' => $query )); })->assert('repo', $app['util.routing']->getRepositoryRegex()) ->assert('branch', $app['util.routing']->getBranchRegex()) + ->convert('branch', 'escaper.argument:escape') ->bind('search'); - - # Intentionally before next statement, because order appears - # to be important, and the other statement got precedence previously. $route->get('{repo}/{format}ball/{branch}', function($repo, $format, $branch) use ($app) { $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); @@ -93,17 +93,11 @@ class TreeController implements ControllerProviderInterface $repository->createArchive($tree, $file, $format); } - return new StreamedResponse(function () use ($file) { - readfile($file); - }, 200, array( - 'Content-type' => ('zip' === $format) ? 'application/zip' : 'application/x-tar', - 'Content-Description' => 'File Transfer', - 'Content-Disposition' => 'attachment; filename="'.$repo.'-'.substr($tree, 0, 6).'.'.$format.'"', - 'Content-Transfer-Encoding' => 'binary', - )); + return new BinaryFileResponse($file); })->assert('format', '(zip|tar)') ->assert('repo', $app['util.routing']->getRepositoryRegex()) ->assert('branch', $app['util.routing']->getBranchRegex()) + ->convert('branch', 'escaper.argument:escape') ->bind('archive'); @@ -111,6 +105,7 @@ class TreeController implements ControllerProviderInterface return $treeController($repo, $branch); })->assert('repo', $app['util.routing']->getRepositoryRegex()) ->assert('branch', $app['util.routing']->getBranchRegex()) + ->convert('branch', 'escaper.argument:escape') ->bind('branch'); $route->get('{repo}/', function($repo) use ($app, $treeController) { diff --git a/git/src/GitList/Escaper/ArgumentEscaper.php b/git/src/GitList/Escaper/ArgumentEscaper.php new file mode 100755 index 00000000..6717dd8a --- /dev/null +++ b/git/src/GitList/Escaper/ArgumentEscaper.php @@ -0,0 +1,15 @@ +%H" - . "%h%T%P" + . "%h%T%P" . "%an%ae" . "%at%cn" . "%ce" @@ -241,9 +241,10 @@ class Repository extends BaseRepository public function searchCommitLog($query) { $query = escapeshellarg($query); + $query = strtr($query, array('[' => '\\[', ']' => '\\]')); $command = "log --grep={$query} --pretty=format:\"%H" - . "%h%T%P" + . "%h%T%P" . "%an%ae" . "%at%cn" . "%ce" @@ -369,7 +370,7 @@ class Repository extends BaseRepository { $fs = new Filesystem; $fs->mkdir(dirname($output)); - $this->getClient()->run($this, "archive --format=$format --output=$output $tree"); + $this->getClient()->run($this, "archive --format=$format --output='$output' $tree"); } /** diff --git a/git/src/GitList/Util/Repository.php b/git/src/GitList/Util/Repository.php index 5f6c80c0..1295276b 100755 --- a/git/src/GitList/Util/Repository.php +++ b/git/src/GitList/Util/Repository.php @@ -40,6 +40,8 @@ class Repository 'md' => 'markdown', 'markdown' => 'markdown', 'sql' => 'mysql', + 'ml' => 'ocaml', + 'mli' => 'ocaml', 'pl' => 'perl', 'pm' => 'perl', 'pas' => 'pascal', @@ -60,6 +62,7 @@ class Repository 'st' => 'smalltalk', 'tex' => 'stex', 'vbs' => 'vbscript', + 'vb' => 'vbscript', 'v' => 'verilog', 'xml' => 'xml', 'xsd' => 'xml', diff --git a/git/src/GitList/Util/Routing.php b/git/src/GitList/Util/Routing.php index 65ea13fe..677f2aac 100755 --- a/git/src/GitList/Util/Routing.php +++ b/git/src/GitList/Util/Routing.php @@ -58,11 +58,18 @@ class Routing } } - if ($matchedBranch === null) { - throw new EmptyRepositoryException('This repository is currently empty. There are no commits.'); + if ($matchedBranch !== null) { + $commitish = $matchedBranch; + } else { + // We may have partial commit hash as our commitish. + $hash = $slashPosition === false ? $commitishPath : substr($commitishPath, 0, $slashPosition); + if ($repository->hasCommit($hash)) { + $commit = $repository->getCommit($hash); + $commitish = $commit->getHash(); + } else { + throw new EmptyRepositoryException('This repository is currently empty. There are no commits.'); + } } - - $commitish = $matchedBranch; } $commitishLength = strlen($commitish); @@ -101,15 +108,15 @@ class Routing static $regex = null; if ($regex === null) { - $app = $this->app; - $self = $this; + $isWindows = $this->isWindows(); $quotedPaths = array_map( - function ($repo) use ($app, $self) { - $repoName = $repo['name']; - //Windows - if ($self->isWindows()){ - $repoName = str_replace('\\', '',$repoName); + function ($repo) use ($isWindows) { + $repoName = preg_quote($repo['name']); + + if ($isWindows) { + $repoName = str_replace('\\', '\\\\', $repoName); } + return $repoName; }, $this->app['git']->getRepositories($this->app['git.repos'])