|
1 | 1 | package Renderer::Controller::StaticFiles;
|
2 | 2 | use Mojo::Base 'Mojolicious::Controller', -signatures;
|
3 | 3 |
|
4 |
| -use Mojo::File qw(path); |
| 4 | +use Mojo::File qw(path); |
| 5 | +use File::Spec::Functions qw(canonpath); |
5 | 6 |
|
6 |
| -sub reply_with_file_if_readable ($c, $file) { |
7 |
| - if (-r $file) { |
8 |
| - return $c->reply->file($file); |
| 7 | +sub path_is_subdir ($path, $dir) { |
| 8 | + return 0 unless $path =~ /^\//; |
| 9 | + |
| 10 | + $path = canonpath($path); |
| 11 | + return 0 if $path =~ m#(^\.\.$|^\.\./|/\.\./|/\.\.$)#; |
| 12 | + |
| 13 | + $dir = canonpath($dir); |
| 14 | + return 0 unless $path =~ m|^$dir|; |
| 15 | + |
| 16 | + return 1; |
| 17 | +} |
| 18 | + |
| 19 | +sub reply_with_file_if_readable ($c, $directory, $file) { |
| 20 | + my $filePath = $directory->child($file); |
| 21 | + if (-r $filePath && path_is_subdir($filePath, $directory)) { |
| 22 | + return $c->reply->file($filePath); |
9 | 23 | } else {
|
10 | 24 | return $c->render(data => 'File not found', status => 404);
|
11 | 25 | }
|
12 | 26 | }
|
13 | 27 |
|
14 | 28 | # Route requests for pg_files/CAPA_Graphics to render root Contrib/CAPA/CAPA_Graphics
|
15 | 29 | sub CAPA_graphics_file ($c) {
|
16 |
| - return $c->reply_with_file_if_readable($c->app->home->child('Contrib/CAPA/CAPA_Graphics', $c->stash('static'))); |
| 30 | + return $c->reply_with_file_if_readable($c->app->home->child('Contrib/CAPA/CAPA_Graphics'), $c->stash('static')); |
17 | 31 | }
|
18 | 32 |
|
19 | 33 | # Route requests for pg_files to the render root tmp. The
|
20 | 34 | # only requests should be for files in the temporary directory.
|
21 | 35 | # FIXME: Perhaps this directory should be configurable.
|
22 | 36 | sub temp_file ($c) {
|
23 |
| - $c->reply_with_file_if_readable($c->app->home->child('tmp', $c->stash('static'))); |
| 37 | + return $c->reply_with_file_if_readable($c->app->home->child('tmp'), $c->stash('static')); |
24 | 38 | }
|
25 | 39 |
|
26 | 40 | # Route request to pg_files to lib/PG/htdocs.
|
27 | 41 | sub pg_file ($c) {
|
28 |
| - $c->reply_with_file_if_readable(path($ENV{PG_ROOT}, 'htdocs', $c->stash('static'))); |
| 42 | + return $c->reply_with_file_if_readable(path($ENV{PG_ROOT}, 'htdocs'), $c->stash('static')); |
29 | 43 | }
|
30 | 44 |
|
31 | 45 | sub public_file ($c) {
|
32 |
| - $c->reply_with_file_if_readable($c->app->home->child('public', $c->stash('static'))); |
| 46 | + return $c->reply_with_file_if_readable($c->app->home->child('public'), $c->stash('static')); |
33 | 47 | }
|
34 | 48 |
|
35 | 49 | 1;
|
0 commit comments